C++でデストラクタとコンストラクタが呼び出される順序は何ですか?いくつかの基本クラスと派生クラスの例を使用する
順序は:
例:
class B
{
public:
B()
{
cout<<"Construct B"<<endl;
}
virtual ~B()
{
cout<<"Destruct B"<<endl;
}
};
class D : public B
{
public:
D()
{
cout<<"Construct D"<<endl;
}
virtual ~D()
{
cout<<"Destruct D"<<endl;
}
};
int main(int argc, char **argv)
{
D d;
return 0;
}
例の出力:
構成B
構築D
破壊D
破壊B
複数レベルの継承はスタックのように機能します:
アイテムを構築としてスタックにプッシュし、それを破棄として削除することを検討する場合は、スタックのような継承の複数のレベルを見ることができます。
これは任意の数のレベルで機能します。
例D2はDから派生しており、Bから派生しています。
スタックにBをプッシュし、スタックにDをプッシュし、スタックにD2をプッシュします。したがって、構築順序はB、D、D2です。次に、破壊命令を見つけるために飛び出し始めます。 D2、D、B
より複雑な例:
より複雑な例については、@ JaredParによって提供されるリンクを参照してください
仮想継承や多重継承など、これらのイベントの詳細な説明は、C++で入手できますFAQ Lite。セクション25.14および25.15
https://isocpp.org/wiki/faq/multiple-inheritance#mi-vi-ctor-order
また、配列要素は最初に作成される->最後に、逆の順序で破壊されることに注意してください:最後->最初。
誰もがそれを無視しているように見えるので、私は以前の答えに加えなければなりません
derivedクラスインスタンスがcreatedである場合、コードinsidebaseのコンストラクタはbeforeコードinsidederived、ただしderivedは技術的にまだ "created"beforeであることを覚えておいてくださいベース。
そして、derivedクラスデストラクタが呼び出されている場合、コードinside派生したデストラクタはbefore前に呼び出されますinsideベースデストラクタですが、baseはdestroyedbeforederived.
created/destroyedと言っているとき、私は実際にはallocated/deallocatedを参照しています。
これらのインスタンスのメモリレイアウトを見ると、派生インスタンスがベースインスタンスを構成していることがわかります。例えば:
派生メモリ:0x00001110〜0x00001120
ベースのメモリ:0x00001114〜0x00001118
したがって、派生クラスは、構造のベース[〜#〜] [〜#〜]の前に割り当てる必要があります。そして、派生クラスは破壊のベースの割り当て解除[〜#〜] [〜#〜]の後でなければなりません。
次のコードがある場合:
class Base
{
public:
Base()
{
std::cout << "\n Base created";
}
virtual ~Base()
{
std::cout << "\n Base destroyed";
}
}
class Derived : public Base
{
public:
Derived()
// Derived is allocated here
// then Base constructor is called to allocate base and prepare it
{
std::cout << "\n Derived created";
}
~Derived()
{
std::cout << "\n Derived destroyed";
}
// Base destructor is called here
// then Derived is deallocated
}
だからあなたが作成した場合Derived d;
そしてそれを範囲外にすると、@ Brianの答えで出力が得られます。しかし、メモリ内のオブジェクトの動作は実際には同じ順序ではなく、次のようになります。
建設:
割り当てられた派生
ベース割り当て
呼び出された基本コンストラクタ
呼び出された派生コンストラクタ
破壊:
派生したデストラクタが呼び出されました
ベースデストラクタが呼び出されました
ベースの割り当て解除
派生した割り当て解除