为什么这段代码不会在类析构函数中调用CloseHandles?
在我的代码测试中,我明确地调用'((MyClass*)pThis)->CloseHandles();',但变量m_bFinished有错误的值 . 为什么?
#include <windows.h>
#include <exception>
class MyClass
{
public:
explicit MyClass( void **pThis)
{
*pThis = this;
m_bFinished = false;
//code open handle here
//an error occurs
throw new std::exception("Exception thrown!");
}
~MyClass()
{
if ( ! m_bFinished ) CloseHandles();
}
void CloseHandles()
{
if ( m_bFinished ) return;
//close handles here.
m_bFinished = true;
}
private:
bool m_bFinished;
};
int main(int argc, char* argv[])
{
MyClass * pMyClass;
void * pThis = NULL;
try
{
pMyClass = new MyClass(&pThis);
}
catch(std::exception * e)
{
//delete pThis;
if ( pThis )
{
((MyClass*)pThis)->CloseHandles();
}
}
return 0;
}
1 回答
因为类的析构函数在其构造函数抛出时不会运行 - 该对象尚未完全初始化 .
另外,你实际上并没有抛出
std::exception
,而是指向它的指针:编辑:我注意到你're catching a pointer, too, so that'不是问题 . 但是,没有
std::exception
的构造函数采用字符串文字,所以我想知道你的代码是如何编译的 .在任何情况下,如果构造函数可能在分配原始资源后抛出,则可能存在泄漏 .
您需要将资源包装在管理它的类中 - 可能是智能指针或类似的RAII包装器 . 并使用member initializer lists!
另一种选择是构造函数委托(C 11中的新增) . 当一个对象的任何构造函数完成执行时,它被认为是完全构造的 . 这意味着如果从委托给另一个构造函数的构造函数抛出异常(您将在其中获取句柄),则将调用析构函数 .
用一些代码来说明:
以及构造函数委派的示例:
输出为
dtor!
.