简体   繁体   English

C++中析构函数和构造函数的调用顺序是什么

[英]What is the order in which the destructors and the constructors are called in C++

What is the order in which the destructors and the constructors are called in C++? C++中析构函数和构造函数的调用顺序是什么? Using the examples of some Base classes and Derived Classes使用一些基类和派生类的例子

The order is:顺序是:

  1. Base constructor基础构造函数
  2. Derived constructor派生构造函数
  3. Derived destructor派生的析构函数
  4. Base destructor基础析构函数

Example:例子:

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;
}

Output of example: Output 的例子:

Construct B构造 B

Construct D构造 D

Destruct D破坏D

Destruct B破坏B

Multiple levels of inheritance works like a stack:多级 inheritance 的工作方式类似于堆栈:

If you consider pushing an item onto the stack as construction, and taking it off as destruction, then you can look at multiple levels of inheritance like a stack.如果您考虑将一个项目推入堆栈作为构造,并将其取出作为破坏,那么您可以像堆栈一样查看 inheritance 的多个级别。

This works for any number of levels.这适用于任意数量的级别。

Example D2 derives from D derives from B.示例 D2 派生自 D 派生自 B。

Push B on the stack, push D on the stack, push D2 on the stack.将 B 压入堆栈,将 D 压入堆栈,将 D2 压入堆栈。 So the construction order is B, D, D2.所以施工顺序是B、D、D2。 Then to find out destruction order start popping.然后找出破坏顺序开始弹出。 D2, D, B D2、D、B

More complicated examples:更复杂的例子:

For more complicated examples, please see the link provided by @JaredPar更复杂的例子请看@JaredPar 提供的链接

A detailed description of these events, including virtual and multiple inheritance is available at the C++ FAQ Lite. C++ FAQ Lite 提供了这些事件的详细描述,包括虚拟和多个 inheritance。 Section 25.14 and 25.15第 25.14 和 25.15 节

https://isocpp.org/wiki/faq/multiple-inheritance#mi-vi-ctor-order https://isocpp.org/wiki/faq/multiple-inheritance#mi-vi-ctor-order

Also, keep in mind that while array elements are constructed first -> last, they are destructed in the reverse order: last -> first.另外,请记住,虽然数组元素是先构造的 -> 最后一个,但它们会以相反的顺序被破坏:最后一个 -> 第一。

I must add to the previous answers because everyone seems to be ignoring it我必须添加到以前的答案,因为每个人似乎都忽略了它

When you have a derived class instance being created , it is true that the code inside the constructor of the base will be called before the code inside the constructor of the derived , but keep in mind that the derived is still technically "created" before the base .当您创建派生class 实例时,确实会在派生构造函数的代码之前调用构造函数的代码,但请记住,派生在技术上仍然是“创建”之前基地

And when you have the derived class destructor being called, it is true that the code inside the derived destructor is called before the code inside the base destructor, but also keep in mind that the base is destroyed before the derived .并且当您调用派生的 class 析构函数时,派生析构函数的代码确实在基析构函数的代码之前被调用,但请记住,基数派生之前销毁

When I am saying created/destroyed I am actually referring to allocated/deallocated .当我说created/destroyed时,我实际上指的是allocated/deallocated

If you look at the memory layout of these instances, you will see that the derived instance composes the base instance.如果您查看这些实例的 memory 布局,您会看到派生实例构成了基础实例。 For example:例如:

Memory of derived: 0x00001110 to 0x00001120 Memory 的派生:0x00001110 到 0x00001120

Memory of base: 0x00001114 to 0x00001118基础的 Memory:0x00001114 到 0x00001118

Therefore, the derived class must be allocated BEFORE the base in the construction.因此,派生的 class 必须在构造中的基础之前分配。 And the derived class must be deallocated AFTER the base in the destruction.并且派生的class必须在销毁基础后释放。

If you have the following code:如果您有以下代码:

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
}

So if you created Derived d;因此,如果您创建了Derived d; and had it go out of scope, then you will get the output in @Brian's answer.并从 scope 中取出 go,然后您将在@Brian 的回答中获得 output。 But the object behavior in memory is not really the in same order, it is more like this:但是 memory 中的 object 行为实际上并不相同,更像是这样:

Construction:建造:

  1. Derived allocated派生分配

  2. Base allocated基地分配

  3. Base constructor called基础构造函数调用

  4. Derived constructor called派生构造函数调用

Destruction:破坏:

  1. Derived destructor called派生的析构函数调用

  2. Base destructor called基析构函数调用

  3. Base deallocated基数解除分配

  4. Derived deallocated派生解除分配

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM