【发布时间】:2019-02-18 23:20:18
【问题描述】:
在我的构造函数中,如果其中的任何代码抛出,我必须销毁任何剩余的资源。我想避免编写重复的代码,所以我只在 catch 块中调用析构函数,而不是释放任何已创建的资源。这安全吗?
我知道如果构造函数抛出,析构函数不会被调用,所以我尝试在 msvc 中编译一些代码,似乎没有任何问题,但我不确定这是否只是运气。
Object::Object(){
try{
// Initialize multiple resources here.
}catch(...){
this->~Object(); // Is this safe?
throw;
}
}
Object::~Object(){
// release multiple resources, if initialized.
}
【问题讨论】:
-
我怀疑这是 UB,但我懒得做研究。拥有
cleanup()函数并从构造函数和析构函数调用它会更安全。更好的是,在 RAII 包装器中保存“多个资源”,以便它们自动释放。 -
如果其中的任何代码抛出,我必须销毁任何剩余的资源 -- RAII 是您应该使用的,而不是显式地对析构函数进行可疑调用。这种类型的析构函数调用几乎总是为
placement-newcleanup 保留。 -
它是 UB,因为在生命周期尚未开始的对象上调用了非平凡的析构函数
-
换句话说:
{ YourResource r1; YourOtherResource r2; }如果r1和r2在右花括号后不能自动清理,那么重新考虑你是如何编写你的类的(或者如前所述, 将这些类型包装到我展示的代码可以正常工作的类中)。
标签: c++ constructor try-catch object-lifetime explicit-destructor-call