前回のエントリで書いたコンストラクタの問題。
それの解答ってことで。間違ってるって場合はコメントくだちい。
まず、何が問題であったか。
前回のコードでは bad_alloc をまったく考えていないですよね。
で、コンストラクタ内で例外が発生し、コンストラクタが正常終了しないと、デストラクタが呼ばれません。これ重要。
なぜならオブジェクトとして生成されないんだから。
初期化リストやコンストラクタ内でメモリ確保を行って、 bad_alloc が発生するとどうなるでしょう。例えば one_ では確保成功、two_ で確保失敗のようなケースです。
one_ で確保したメモリはデストラクタが呼ばれないので解放されんのです。リーク。
解決策としては下記のようなコードを書きます。
-
class Hoge
-
{
-
public:
-
Hoge() : one_(0), two_(0)
-
{
-
try {
-
one_ = new A;
-
two_ = new B;
-
}
-
catch (...) {
-
delete one_;
-
delete two_;
-
}
-
}
-
-
~Hoge() {
-
delete one_;
-
delete two_;
-
}
-
-
private:
-
A* one_;
-
B* two_;
-
};
先日のコードだと長いので要素を減らしましたが、やってることといえば 例外をキャッチして後始末をする ってだけです。
メモリ解放に失敗してもコンストラクタは成功し、デストラクタも呼ばれます。
初期化リストではヌルポでも入れておきましょう。
# Seasons 氏に言われたので 補足しときますね。
# 上記例では int でメモリ確保してますけど、これは例ですので、 class とかに置き換えて考えてくだちい。
# アキラ 氏につっこみ貰いましたので、ソースを修正しました (2008/06/10)
# ついでに、クラスが持つメンバ変数を class A, class B のようなものにしてみました (2008/06/10)
