質問編集履歴

1 ソースコードの追加

BeatStar

BeatStar score 1846

2016/05/16 12:59  投稿

コンストラクタから例外を投げたときのdelete
C/C++ でやっています。
インターフェースクラスを用意し、インターフェースクラスを継承してできた子クラスをFactoryMethodパターンで実体として生成します。
そのとき、この子クラスから例外が投げられるときのdeleteがうまくいきません。
たとえば、
1. ITestクラスから継承してCTestクラスを定義
2. CreateInstance関数 ( グローバル関数 ) で FactoryMethodパターンで CTestの実体を生成& ITest* として返す
3. CTestクラスのコンストラクタでは、引数が指定データでなければ例外を投げる
4. main関数等の呼び出し側で例外処理
という感じでやっています。
このとき、
例外が投げられないとき ( throw文を削除 ) と 例外が発生しないとき は普通に動くのですが、
例外が発生したときに 実行時エラーになります。
newを使わない方法で生成する場合はうまくいくようですが、
DLLから クラスオブジェクトを取得し操作する
という感じでやりたいのでnew/deleteを使う方法になります。
ですが、delete のところがなぜか実行時エラー。
サンプルでは、
1. 例外を受け取る ( catch )
2. cout << 3 << endl;
3. delete で破棄
4. cout << 4 << endl;
となっているので、
本来なら、
3
( デストラクタ起動 )
4
みたいに印字されるはずですが、
3
のところで止まってしまいます。 ( エラーになる。 )
解決方法ってないのでしょうか。
一応自分でも調べたのですが、「コンストラクタから例外を投げるな」、「コンストラクタで初期化失敗した場合、唯一の連絡手段は例外処理である」、「(例外処理が発生した場合)メモリの確保に対する破棄等はコンストラクタ内で行うべき」といろいろあり、わかりづらいです...
特に, インターフェースでnewで生成して、前処理等でなんらかのエラーがあった場合にコンストラクタから例外が投げられるときの
呼び出し側 ( main関数等 ) での書き方です。
```C++  
#include<iostream>  
using namespace std;  
 
// インターフェースクラス  
class ITest{  
     public:  
              virtual ~ITest(){}  
              virtual int func() = 0;  
};  
 
// 実際に使いたいクラス  
class CTest : public ITest{  
     private:  
               bool bCheck;  
     protected:  
     public:  
               CTest( bool bCheck = false );  
               ~CTest();  
                 
               int func();  
};  
 
// 子クラスのコンストラクタ  
CTest::CTest( bool bCheck ){  
      if( bCheck == false ) throw -1;  
      this->bCheck = bCheck;  
}  
 
// 子クラスのデストラクタ  
CTest::~CTest(){  
      cout << "Destructor" << endl;  
}  
 
// 子クラスのメンバ関数  
int CTest::func(){  
    return 100;  
}  
 
 
// FactoryMethod を利用して 生成する関数  
ITest* CreateInstance( bool bCheck ){  
      return new CTest( bCheck );  
}  
 
 
int main( int argc, char *argv[] )  
{  
       ITest* obj;  
   try{  
        cout << 1 << endl;  
        obj = CreateInstance( false );  
        cout << 2 << endl;  
   }catch(int n){  
        cout << 3 << endl;  
        delete obj; // ここで実行時エラー.  
        cout << 4 << endl;  
   }  
     
   // 停止用  
   getchar();getchar();  
return 0;  
}  
 
```  
[環境等]
言語: C/C++
知りたいこと: FactoryMethodパターンで子クラスを生成するとき、コンストラクタから例外が投げられたときのオブジェクト破棄する方法
宜しくお願い致します。
  • C++

    7619 questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る