1

私の例外のメカニズムの研究中に、スタックの巻き戻し中にオブジェクトのフィールドのデストラクタの呼び出しがあることがわかりました。明示的に説明しましょう:

class X
{
  File_ptr aa;
  Lock_ptr bb;
public:
 X(const char* x,const char* y):aa(x),bb(y){}
//.......
}

したがって、Lock_ptr のコンストラクターが例外をスローすると、オブジェクトaaは破棄されます。問題は「なぜ」ですか?私は常に、オブジェクトのフィールドは通常の自動 (ローカル) オブジェクトではないと考えていました。それらは、コンストラクターがそれらを初期化する前に作成されます。コンストラクターは作業を終了しました)

4

3 に答える 3

5

サブオブジェクト (非静的データ メンバーを含む) は、それらが属する完全なオブジェクトと同じ保存期間を持ちます。これは、それらが自動的であると言っているのと同じではありません。自動オブジェクトは、ブロックの最後で破棄されます。サブオブジェクトは、完全なオブジェクトが破棄されるたびに破棄されます。たとえば、完全なオブジェクトが で作成され、newで破棄されるdelete(つまり、動的な保存期間がある) 場合、サブオブジェクトも の呼び出しで作成され、 の呼び出しnewで破棄されdeleteます。一方、自動オブジェクトのサブオブジェクトも自動です。

のコンストラクターがX::bb例外をスローする場合は、型の完全なオブジェクトをX構築できないことを意味します。X::aa完全なオブジェクトと同じ保存期間を持つサブオブジェクトは、完全なオブジェクトなしでは存続できないため、 などの既に構築されているすべてのサブオブジェクトを破棄する必要があります。

一方、Xオブジェクト全体の構築が正常に完了した場合X::aa、完全なオブジェクトが破棄されるまで (直後に) 他のサブオブジェクトは破棄されませんX

C++ の構築規則と破棄規則は、プログラムが正常に終了する限り、作成されたすべてのオブジェクトも 1 回だけ破棄されることを保証することを目的としています。これは、RAII イディオムにとって不可欠です。この例でX::aaは、構築時にリソースを取得する場合、言語はそれらのリソースが解放されることを保証する必要があります。の構築が失敗しX::aaたときに のデストラクタが呼び出されない場合、いつ呼び出す必要がありますか?X

于 2014-06-27T17:54:33.137 に答える
3

X には、 and を構築する「実際の」コンストラクターがaaありbb、その後、X のコンストラクター本体が呼び出されます。これが、イニシャライザ リストがXのコンストラクタ「本体」の前にある理由です。この「実際の」コンストラクターの内部では、スタックの巻き戻しを含め、クラスで宣言されている順序でスタック上にあるかのように、ベースとメンバーが作成されます。私も写真を持っています: ここに画像の説明を入力

デストラクタは、逆の場合を除いて、漠然と似た原理で動作しますが、デストラクタが仮想の場合はさらに複雑になる可能性があります。デストラクタが仮想の場合、3 つの部分があります。誰かがデストラクタを呼び出すと呼び出される「スタブ」デストラクタがあり、最も派生した型の「実際の」デストラクタにディスパッチされます。「実際の」デストラクタはデストラクタを「本体」と呼び、クラスで宣言されている順序と逆の順序でメンバーを破棄し、基本クラスを破棄します (逆の順序で、スタックと同じです)。

*QuestionC は、静的メンバーがここに書いたすべてのものから完全に独立していることを正しく観察しています。

于 2014-06-27T17:45:55.043 に答える
0

staticクラス コンストラクターが呼び出されると、メンバー オブジェクト ( でない限り) が構築されます。表示されている動作は正常で正しいものです。

コンストラクターが終了しても、メンバー オブジェクトは破棄されません。これらは、クラス デストラクタが呼び出されると破棄されます (構築の逆順)。

于 2014-06-27T17:49:24.013 に答える