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で質問しましょう!
似たような質問が見つかりました
- Java Javaのソースコード作成が難しいです... 10 2022/11/11 14:06
- Java すみません。助けてください。 javaについての質問です。 integerに変換できない数値をエラー 5 2022/05/18 19:16
- PHP DBのハッシュ化したパスワードをpassword_verifyで戻し照合したのですが上手く行きません 2 2023/02/06 13:24
- C言語・C++・C# C# で、あるフォルダー内にあるすべてのテキストファイルを別のフォルダーにコピーする。 4 2022/11/21 13:23
- その他(プログラミング・Web制作) zshの例外処理 1 2022/06/02 16:36
- JavaScript セレクトを全て選択されていないと、文字によるエラーメッセージを表示させるコードを調べています 2 2023/06/22 15:48
- PHP PHP一覧表示した項目にリンクをはりたい 1 2023/07/12 17:08
- 画像編集・動画編集・音楽編集 DVD Styler トラブル解決方法 6 2022/10/29 16:00
- JavaScript WordPressのコンタクトフォーム7にて送信者の位置情報を送らせたい 2 2022/09/14 23:28
- C言語・C++・C# C#のSystem.Windows.Media.Colorに関する質問です。 3 2022/05/18 11:51
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
worksheetFunctionクラスのVloo...
-
「Columns("A:C")」の列文字を...
-
エクセルのVBAの標準モジュール...
-
AccessVBAで「dim dbs as datab...
-
UserForm1.Showでエラーになり...
-
VBScriptでファイルの日時順(降...
-
実行時エラー 3265「要求された...
-
VBAで既に開いている別アプリケ...
-
エクセルVBAで2つの画像を比較...
-
EXCEL VBA オートシェイプナン...
-
VBAについてです。 初心者です...
-
VB6 ファイルのリネームの仕方
-
オブジェクト名が同じ図形の変更
-
エクセルVBAでFor each文
-
VBScriptでの起動済みのIEの操作
-
ある文字列が全て数字であるか...
-
Excelでフィルタをかけると警告...
-
VBからPDFファイル自動生成...
-
osversioninfoのオブジェクトが...
-
Excel VBA グラフを任意sheetに...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
worksheetFunctionクラスのVloo...
-
「Columns("A:C")」の列文字を...
-
エクセルのVBAの標準モジュール...
-
実行時エラー 3265「要求された...
-
VBAで既に開いている別アプリケ...
-
VBAからPDFファイルにパスワー...
-
ある文字列が全て数字であるか...
-
VBAで Set wb = Sheets(1).Cop...
-
VBからPDFファイル自動生成...
-
PowerPointVBAでスライドマスタ...
-
エクセルVBAでcode128のバー...
-
VBで引数にDictionaryオブジェ...
-
EXCEL VBA オートシェイプナン...
-
エクセルマクロエラー「'Cells'...
-
テキストボックス中の文字列の...
-
VBScriptでファイルの日時順(降...
-
Excelでフィルタをかけると警告...
-
上下の位置揃えについて
-
Excel VBAでWordの複数ファイル...
-
EDINETの情報をEXCELにダウンロ...
おすすめ情報