
try-catchでメモリ確保を含むクラスをスローした場合、デストラクタはどの時点で働くのか、教えてください。たとえば、↓の使いかたは大丈夫でしょうか?
【1】
try{
throw(CError(100, "エラー情報"));
}catch(CError& err){
//ここでerrを参照しても問題ないのでしょうか?
}
【2】
try{
CError err(100, "エラー情報");
throw(err); // (1)
}catch(CError& err){
//ここでerrを参照しても問題ないのでしょうか?
//まだデストラクタはちゃんと動作するのでしょうか?
//catchが呼び出し元のメンバであったりしても大丈夫なのでしょうか?
}
宜しくお願いします。
No.3ベストアンサー
- 回答日時:
【1】【2】どちらの場合も問題がありません。
コンパイラが必要に応じてerrオブジェクトのコピーを作成します。
デストラクタが呼び出されるタイミングはコンパイラに依存するところもあると思いますが、
例えばVC7.1では【2】は以下のように動作します。
(1) errオブジェクトのコンストラクタが呼び出される
(2) CErrorクラスのテンポラリオブジェクト(以下a)のコピーコンストラクタが呼び出される。
(3) errオブジェクトのデストラクタが呼び出される
(4) catch文まで到達
(5) aオブジェクトのデストラクタが呼び出される。
VC7.1では、【1】は以下のように動作します。
(1) errオブジェクトのコンストラクタが呼び出される
(2) catch文まで到達
(3) errオブジェクトのデストラクタが呼び出される。
コンパイラがオブジェクトのコピーを省略しているようです。
わかりやすくて、とても理解の助けになりました。
【2】の動作がいまいち納得がいきませんが、とりあえずコピーコンストラクタで間違えない作りであれば、大丈夫そうですね。
ありがとうございました。
No.4
- 回答日時:
#1です。
ちょっと説明不足でした。
throw test();
とすると、コピーコンストラクタが省略されるかどうかはコンパイラに依存します(最近は省略される方が多い)。
No.2
- 回答日時:
throw Test();
で生成と同時に例外を投げると、
コピーコンストラクタが呼ばれないように見えますね。
----------- 使用したコード ---------
struct Test {
// 省略
};
int main()
{
try {
cerr << "throw!" << endl;
throw Test();
}
catch (Test const& test) {
cerr << "catch!" << endl;
}
return 0;
}
---------- 実行した結果 -------------
$ ./test
throw!
Test::Test()
catch!
Test::~Test()
---------- 環境 ---------------------
FreeBSD 6.3-RELEASE-p2
g++ 3.4.6
-------------------------------------
throw Test();
の箇所を
Test test;
throw test;
にすると、try ブロックで test がコピーされた後に破棄されますが。
環境依存なのかなあ?
No.1
- 回答日時:
言葉で説明するより、実験した方がよいと思います。
例えば、
struct test
{
test() { std::puts("test::test()"); }
test(const test& other) { std::puts("test::test(other);"); }
~test() { std::puts("test::~test();"); }
};
といったクラスを定義して、
throw test();
のように例外オブジェクトを送出してみてください。
試してみれば、コピーコンストラクタを定義した意味も分かるはずです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
worksheetFunctionクラスのVloo...
-
VBAからPDFファイルにパスワー...
-
エクセルのVBAの標準モジュール...
-
「Columns("A:C")」の列文字を...
-
Excelでフィルタをかけると警告...
-
実行時エラー 3265「要求された...
-
VBA:オートシェイプの線の長...
-
VBA msoShapeBlockArcで扇形の...
-
上下の位置揃えについて
-
エクセル エラー438
-
Word2007数式でIMEオン/オフを...
-
VBA オブジェクトが空かどうか...
-
VBAでエクセルに入力された複数...
-
ある文字列が全て数字であるか...
-
VBAでWebページにセルの値を入力
-
VBでPDFファイルを編集する
-
エクセルマクロエラー「'Cells'...
-
Excel VBA オブジェクトマクロ ...
-
AccessVBAで「dim dbs as datab...
-
Excel VBA Collection.add で R...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
worksheetFunctionクラスのVloo...
-
「Columns("A:C")」の列文字を...
-
PowerPointVBAでスライドマスタ...
-
エクセルのVBAの標準モジュール...
-
Excelでフィルタをかけると警告...
-
実行時エラー 3265「要求された...
-
テキストボックス中の文字列の...
-
VBAからPDFファイルにパスワー...
-
VBAで既に開いている別アプリケ...
-
Excel VBAでIEにアクセスするプ...
-
オブジェクトが見つかりません
-
ExcelVBAでのNZ関数について
-
エクセルVBAでcode128のバー...
-
WordにOLEで埋め込んだExcelでW...
-
AccessVBAで「dim dbs as datab...
-
エクセルマクロエラー「'Cells'...
-
エクセル エラー438
-
[VBA]CDOメッセージ送信エラー
-
VBAで作成するメール(開封確認...
-
VBScriptでファイルの日時順(降...
おすすめ情報