空ではない例外宣言を含む C++ デストラクターが宣言されています。
デストラクターに空ではない例外宣言が含まれている場合、デストラクターから例外がスローされる可能性があることを示します。ただし、次の 2 つの理由から、C++ デストラクターは例外をスローすべきではありません。1 つ目の理由として、C++ オブジェクトは、例外が許可されていないコンテキストで暗黙的に破棄されます。例えば、例外 E1 をスローするデストラクターを持つオブジェクト X のインスタンスをブロックの中で宣言して、 別の例外 E2 をスローしてそのブロックを終了する場合、 C++ ランタイムは E1 と E2 の両方の例外ハンドラーを実行することはできません。どちらか一方を選択すると、もう片方の例外は失われます。例外を失うことはできないため、C++ ランタイムは、プロセスを直ちに終了する terminate() を呼び出します。
2 つ目の理由として、デストラクターが例外のスローに成功し、例外が正しく処理されたとしても、アプリケーションでメモリーリークが発生します。オブジェクトの削除では、最初にデストラクターが呼び出され、次に delete 演算子が呼び出されます。実際にストレージを解放するのは delete 演算子です。デストラクターが例外をスローして、delete 演算子が呼び出されなかった場合、メモリーリークが発生します。
ID |
問題箇所 |
説明 |
---|---|---|
1 |
定義 |
デストラクターが定義された場所 |
#include <stdio.h> #include <string.h> class e1 { private: char msg[100]; public: e1(char *p) { strncpy(msg, p, sizeof(msg)); } char *tostring() { return msg; } }; class e2 { private: char msg[100]; public: e2(char *p) { strncpy(msg, p, sizeof(msg)); } char *tostring() { return msg; } }; class m { private: char msg[100]; public: m(char *p) { strncpy(msg, p, sizeof(msg)); } char *tostring() { return msg; } ~m() throw(e1) { if (msg[0] == 'h') throw e1(msg); // bad idea } }; void f() { m myVar("help"); throw new e2("me"); // program fails here: can't throw both e1 and e2 } int main(int argc, char **argv) { try { f(); } catch (e1 e) { printf("caught e1; msg=%s\n", e.tostring()); } catch (e2 e) { printf("caught e2; msg=%s\n", e.tostring()); } }
© 2010 Intel Corporation. 無断での引用、転載を禁じます。