デストラクタは、スタックの通常のアンワインド時と例外がスローされたときに呼び出されますが、exit()が呼び出されたときは呼び出されません。
私のデストラクタが呼び出されない他のケースはありますか? SIGINTやSIGSEGVなどの信号はどうですか? SIGSEGVの場合は呼び出されないと思いますが、SIGNINTの場合は呼び出されますが、どの信号がスタックを巻き戻すかをどのように知ることができますか?
彼らが呼ばれない他の状況はありますか?
彼ら[デストラクタ]が呼び出されない他の状況はありますか?
C++標準では、特定の信号の処理方法については何も述べられていません。多くの実装ではSIGINT
などがサポートされていない可能性があります。exit()
またはabort()
またはterminate()
が呼び出されます。
編集: C++標準をすばやく検索したところ、信号がオブジェクトの存続期間とどのように相互作用するかを指定するものが見つかりません-おそらく私よりも優れた標準を持つ人-fuは何かを見つけることができますか?
さらに編集:別の質問に答えているときに、私はこれを標準で見つけました:
スコープを終了すると(ただし、達成されます)、デストラクタ(12.4)は、そのスコープで宣言された自動ストレージ期間(3.7.2)のすべての構築済みオブジェクト(名前付きオブジェクトまたは一時オブジェクト)に対して、宣言の逆の順序で呼び出されます。
したがって、信号を受信したときにデストラクタを呼び出す必要があるようです。
シグナルそれ自体は現在のスレッドの実行に影響を与えません。したがって、デストラクタの呼び出しは影響を受けません。これは、オブジェクトが存在する独自のスタックを持つ異なる実行コンテキストであるためです。存在しない。これは割り込みのようなものです。実行コンテキストの外部で処理され、処理されると、制御がプログラムに返されます。
マルチスレッドの場合と同じように、C++ 言語はシグナルの概念を知りません。これら2つは互いに完全に直交しており、2つの無関係な標準によって指定されています。それらがどのように相互作用するかは、どちらの標準にも違反しない限り、実装次第です。
補足として、別のケースは、オブジェクトのデストラクタが呼び出されない場合、そのコンストラクタが例外をスローする場合です。ただし、メンバーのデストラクタは引き続き呼び出されます。
それらが呼び出されないもう1つのケースは、ポリモーフィズムを使用していて、ベースデストラクタを仮想化していない場合です。
関数またはメソッドにthrows仕様があり、仕様でカバーされていないものをスローする場合、デフォルトの動作はすぐに終了します。スタックは巻き戻されず、デストラクタは呼び出されません。
POSIXシグナルは、オペレーティングシステム固有の構造であり、C++オブジェクトスコープの概念はありません。一般に、シグナルをトラップし、グローバルフラグ変数を設定し、シグナルハンドラーの終了後に、C++コードで後で処理する以外は、シグナルに対して何もできません。
GCCの最近のバージョンでは、同期シグナルハンドラー内から例外をスローできます。これにより、予期される巻き戻しと破棄のプロセスが発生します。ただし、これはオペレーティングシステムとコンパイラに固有のものです。
abort
Standardが言うように、自動または静的ストレージ期間のオブジェクトのデストラクタを実行せずにプログラムを終了します。その他の状況については、実装固有のドキュメントを読む必要があります。
ここにはたくさんの答えがありますが、まだ不完全です!
デストラクタが実行されない別のケースを見つけました。これは、例外がライブラリの境界を越えてキャッチされたときに常に発生します。
詳細はこちらをご覧ください:
デストラクタが呼び出される状況は基本的に2つあります。関数の最後(または例外)でスタックアンワインド時に、誰か(または参照カウンタ)がdeleteを呼び出した場合。
1つの特別な状況は、静的オブジェクトに見られることです。これらは、プログラムの最後にat_exitを介して破棄されますが、これは2番目の状況です。
どのシグナルがat_exitを通過するかによって異なり、kill -9はプロセスをすぐに強制終了し、他のシグナルは終了するように指示しますが、シグナルコールバックにどの程度正確に依存します。