C ++析构函数:未定义的行为与否?

时间:2012-06-17 16:02:43

标签: c++ destructor

考虑以下代码

#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

我的问题是:我是否正确地思考或上述是未定义的行为,并且可能因编译器而异;

2 个答案:

答案 0 :(得分:11)

它没有变化,自动存储器(堆栈)中的对象按照创建它们的相反顺序被破坏。它完全由标准规定。

C ++ 03 15.2。构造函数和析构函数

  
      
  1. [...]自动对象按照完成构造的相反顺序销毁。
  2.   

答案 1 :(得分: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
}