ネタ元:コンストラクタで例外はありか?のコメントより
試してみました。環境はVS2010。ほかに手元にないしね。
まずは、前回のものを動くやつにしたもの。
#include <crtdbg.h>
#include <exception>
class A
{
public:
A( bool exp )
: value( exp )
{
throw std::exception();
}
~A()
{
}
public:
bool value;
};
int _tmain(int argc, _TCHAR* argv[])
{
_CrtSetDbgFlag( _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG )|_CRTDBG_ALLOC_MEM_DF|_CRTDBG_LEAK_CHECK_DF );
A* a = nullptr;
try{
a = new A( true );
}
catch(...)
{
}
delete a;
return 0;
}
例外はもちろん発生しますが、メモリーリークは発生せず、きちんと解放されていました。
複数階層も試してみました。
#include <crtdbg.h>
#include <exception>
class B
{
public:
B( bool exp )
: val( exp )
{
throw std::exception();
}
public:
bool val;
};
class A
{
public:
A( bool exp )
: value( nullptr )
{
value = new B( exp );
}
~A()
{
delete value;
}
public:
B* value;
};
int _tmain(int argc, _TCHAR* argv[])
{
_CrtSetDbgFlag( _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG )|_CRTDBG_ALLOC_MEM_DF|_CRTDBG_LEAK_CHECK_DF );
A* a = nullptr;
try{
a = new A( true );
}
catch(...)
{
}
delete a;
return 0;
}
A,Bともにメモリーリークせずに解放されます。
おそらく一番ありがちじゃないかな?と思いますが。。。
#include <crtdbg.h>
#include <exception>
class B
{
public:
B( bool exp )
: val( exp )
{
}
public:
bool val;
};
class A
{
public:
A( bool exp )
: value( nullptr )
{
value = new B( exp );
if( exp ){
throw std::exception();
}
}
~A()
{
delete value;
}
public:
B* value;
};
int _tmain(int argc, _TCHAR* argv[])
{
_CrtSetDbgFlag( _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG )|_CRTDBG_ALLOC_MEM_DF|_CRTDBG_LEAK_CHECK_DF );
A* a = nullptr;
try{
a = new A( true );
}
catch(...)
{
}
delete a;
return 0;
}
こちらは、メモリーリークしました。Bだけですけど。まぁメモリアロケート後の例外ですからね。そりゃトラップするほうが無理ってもんです。。。