我是否必须按顺序

时间:2016-12-27 17:37:13

标签: c++ class struct destructor

我知道当为您提供隐式构造函数时,您的类成员将从左到右,从上到下进行初始化。换句话说,按照他们宣布的顺序。然后当类对象超出范围时,所有成员都以相反的顺序被破坏。但是,如果我必须自己摧毁成员,我必须按照它们列出的确切顺序进行吗?例如:

struct Dog {};

struct Animal
{
    Dog* dog1 = new Dog;
    Dog* dog2 = new Dog;
    ~Animal() 
    {
        delete dog2;     // First delete dog2
        delete dog1;     // Then delete dog1
    // Or do I?
    }
};

我认为提供的析构函数是空的。因此,当我听到该类在超出范围时会调用其成员的析构函数时,它不会在自己的析构函数中执行此操作,但在此之后,编译器会单独生成代码吗?例如:

struct Animal
{
     Dog dog1;
     // ~Animal(){}implicitly defined destructor here. dog1 isn't destroyed here
    // But is destroyed here, or after, or something along those lines with separate code that the compiler generates?

};

感谢。

4 个答案:

答案 0 :(得分:5)

  

但是,如果我必须自己摧毁成员,我必须按照它们列出的确切顺序进行吗?

不,按照你喜欢的顺序做。

但我更喜欢匹配"自动"为了避免感到惊讶。

  

我认为提供的析构函数是空的。因此,当我听到该类在超出范围时将调用其成员的析构函数时,它不会在自己的析构函数中执行此操作,但在此之后,编译器会单独生成代码吗?

基本上,是的。

析构函数体的执行是破坏的一部分。另一部分是对所有成员和基地的破坏。

答案 1 :(得分:3)

请记住,删除指针指向的对象和销毁指针本身之间存在区别。当包含对象的生命周期结束时,C ++将自动销毁指针本身,并且它将按照构造它们的顺序反向执行。您可以按照您喜欢的任何顺序自由删除这些指针,具体取决于对象的设置方式。

作为一个注释,如果你从使用原始指针改为unique_ptr s,那么这将完全为你处理,甚至根本不需要一个析构函数!

答案 2 :(得分:1)

在析构函数中销毁对象的顺序通常无关紧要,除非有某些原因它应该基于对象拥有的资源需求。

例如,如果要删除拥有的线程对象,则可能需要在删除线程可能使用的项之前确保该线程已退出。 shared_ptr和其他智能指针在这些情况下很有用。它们还有助于减少对析构函数的需求。

答案 3 :(得分:1)

正如Orbit中的Lightness Races所回答,你可以按照任何命令摧毁班级成员。但是默认的析构函数(如果没有显式调用)总是遵循特定的顺序来销毁成员,这些成员的顺序与创建的成员的顺序相反。

由于析构函数也是一个函数,您可以在该函数中添加语句,以便在对象的销毁时执行。然后,析构函数将执行这些语句,然后,它将以相反的顺序继续删除类的成员。

例如:

struct Dog {};

struct Animal
{
    Dog* dog1 = new Dog;
    Dog* dog2 = new Dog;
    int var;

    ~Animal() 
    {
        delete dog1;     // First delete dog1
    }   //delete var and then delete dog2
};

析构函数将执行它的正文,然后它将开始以相反的顺序删除它的剩余成员。