3

次のコードを検討してください

#include<iostream>
#include<string>

class A
{
    private:
        char name[10];

    public:
        A() { }
        A(const char *str)
        {
            strcpy(name, str);
            std::cout<<name<<" constructed"<<endl; 
        }
        ~A()
        {
           std::cout<<name<<" destructed"<<endl;
        }
};

int main()
{
   A a("a");
   A b("b");
   return 0;
}

次のプログラムの O/P は次のようになります。

a constructed
b constructed
b destructed
a destructed

上記のコードについて私が持っている唯一の説明は、が のb後に作成されたため、スタックのa上に格納する必要があるということです。aメインが終了すると、b最初に がポップアウトされ、次に がポップアウトされたaため、そのデストラクタが最初に呼び出され、次に が呼び出されましaた。

私の質問は次のとおりです。そう考えるのは正しいですか、それとも上記は未定義の動作であり、コンパイラごとに異なる可能性がありますか?

4

2 に答える 2

11

自動メモリ(スタック)内のオブジェクトは、作成された順序とは逆の順序で破棄されます。規格で完全に指定されています。

C++03 15.2. コンストラクタとデストラクタ

  1. [...] 自動オブジェクトは、構築完了の逆の順序で破壊されます。
于 2012-06-17T16:04:22.533 に答える
3

破壊の順序が重要である理由は次のとおりです(作成順序を逆にする必要があります)

class Foo
{
public:
  void foo() { /* ... */ }
};

class Bar
{
public:
   Bar(Foo const & foo) foo(foo) {}
   virtual ~Bar() { this->foo.foo(); }

   Foo const & foo;
};

int main()
{
  Foo foo;
  Bar bar(foo);
  // if foo gets destroyed before bar, then bar will call method foo() on invalid reference in its destructor
  // it is much more convenient to have bar destroyed before foo in such cases
}
于 2012-06-17T17:20:06.663 に答える