コンストラクタ内で例外が起こった場合の処理について
C++でコンストラクタ内で例外が起こった場合、デストラクタが呼ばれないのでコンストラクタ内で確保したメモリはコンストラクタ内できちんと解放しておかないといけない。
C++ではNULL(0)ポインタに対するdeleteが問題ないことになっているのでそれをうまく利用して以下のように書いておくといい。
ここではaのリソースを確保した後にエラーを発生させている(bは領域確保されていない)。
ポイントはポインタの初期化で、bをb(0)と初期化している点。これをしていないでdelete bしてしまうと二重エラーになってアプリケーションがその場でお陀仏するのでこれ大事。ここではコピーコンストラクタは省略*1
#include <iostream> using namespace std; class TSample { private : int *a; int *b; public : TSample() : a(0),b(0){ try{ a = new int(3); throw("Error occurs in Object creation"); b = new int(4); } catch(...){ delete b; delete a; throw; } } ~TSample(){ delete b; delete a; } }; int main() { try{ TSample *x = new TSample(); cout << "Object is created" << endl; } catch(const char* str){ cout << str << endl; } return 0; }
*1:このままだとシャローコピーになって、メモリの二重解放が起きる