C/C++ でやっています。
インターフェースクラスを用意し、インターフェースクラスを継承してできた子クラスをFactoryMethodパターンで実体として生成します。
そのとき、この子クラスから例外が投げられるときのdeleteがうまくいきません。
たとえば、
- ITestクラスから継承してCTestクラスを定義
- CreateInstance関数 ( グローバル関数 ) で FactoryMethodパターンで CTestの実体を生成& ITest* として返す
- CTestクラスのコンストラクタでは、引数が指定データでなければ例外を投げる
- main関数等の呼び出し側で例外処理
という感じでやっています。
このとき、
例外が投げられないとき ( throw文を削除 ) と 例外が発生しないとき は普通に動くのですが、
例外が発生したときに 実行時エラーになります。
newを使わない方法で生成する場合はうまくいくようですが、
DLLから クラスオブジェクトを取得し操作する
という感じでやりたいのでnew/deleteを使う方法になります。
ですが、delete のところがなぜか実行時エラー。
サンプルでは、
- 例外を受け取る ( catch )
- cout << 3 << endl;
- delete で破棄
- cout << 4 << endl;
となっているので、
本来なら、
3
( デストラクタ起動 )
4
みたいに印字されるはずですが、
3
のところで止まってしまいます。 ( エラーになる。 )
解決方法ってないのでしょうか。
一応自分でも調べたのですが、「コンストラクタから例外を投げるな」、「コンストラクタで初期化失敗した場合、唯一の連絡手段は例外処理である」、「(例外処理が発生した場合)メモリの確保に対する破棄等はコンストラクタ内で行うべき」といろいろあり、わかりづらいです...
特に, インターフェースでnewで生成して、前処理等でなんらかのエラーがあった場合にコンストラクタから例外が投げられるときの
呼び出し側 ( main関数等 ) での書き方です。
C++
1#include<iostream> 2 3using namespace std; 4 5// インターフェースクラス 6class ITest{ 7 public: 8 virtual ~ITest(){} 9 virtual int func() = 0; 10}; 11 12// 実際に使いたいクラス 13class CTest : public ITest{ 14 private: 15 bool bCheck; 16 protected: 17 public: 18 CTest( bool bCheck = false ); 19 ~CTest(); 20 21 int func(); 22}; 23 24// 子クラスのコンストラクタ 25CTest::CTest( bool bCheck ){ 26 if( bCheck == false ) throw -1; 27 this->bCheck = bCheck; 28} 29 30// 子クラスのデストラクタ 31CTest::~CTest(){ 32 cout << "Destructor" << endl; 33} 34 35// 子クラスのメンバ関数 36int CTest::func(){ 37 return 100; 38} 39 40 41// FactoryMethod を利用して 生成する関数 42ITest* CreateInstance( bool bCheck ){ 43 return new CTest( bCheck ); 44} 45 46 47int main( int argc, char *argv[] ) 48{ 49 ITest* obj; 50 try{ 51 cout << 1 << endl; 52 obj = CreateInstance( false ); 53 cout << 2 << endl; 54 }catch(int n){ 55 cout << 3 << endl; 56 delete obj; // ここで実行時エラー. 57 cout << 4 << endl; 58 } 59 60 // 停止用 61 getchar();getchar(); 62return 0; 63} 64
[環境等]
言語: C/C++
知りたいこと: FactoryMethodパターンで子クラスを生成するとき、コンストラクタから例外が投げられたときのオブジェクト破棄する方法
宜しくお願い致します。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/05/16 04:05
2016/05/16 05:05
2016/05/16 07:46
2016/05/16 08:58