析构函数顺序

Pau*_*ulH 2 c++

我有一个C++类层次结构,看起来像这样:

class A;

class B
{
public:
    B( A& a ) : a_( a )
    {
    };

private:
    A& a_;
};

class MyObject
{
public:
    MyObject() : b_( a_ )
    {
    };

private:
    A a_;
    B b_;
};
Run Code Online (Sandbox Code Playgroud)

偶尔会发生在B的析构函数中,我将获得与其A的引用相关的无效访问异常.看来A在B之前被销毁.

使用类成员初始化其他成员是否存在固有的错误?是否无法保证破坏的顺序?

谢谢,PaulH

Fer*_*yer 6

编辑:我错过了MyObject你的部分问题,所以我的原始答案可能没有多大帮助.我猜你的问题在于你没有发布的代码,精简的例子应该可以正常工作.


B不"自己的"通过引用传递的对象,因此,对象ab具有不同的生命周期.如果被引用的对象B::a_被销毁,则B析构函数将访问无效的引用.

一些代码来解释我的意思:

class A;

class B {
public:
    B(A a) : a_(a) {}  // a is copied to a_
    ~B() { /* Access a_ */ }
private:
    A a_;
};

class C {
public:
    C(A& a) : a_(a) {}  // a_ is a reference (implicit pointer)
                        // of an external object.
    ~C() { /* Access a_ */ }
private:
    A& a_;
};


int main(int argc, char** argv) {
    A* a = new A();

    B b(*a);
    C c(*a);

    delete a;
    // Now b has a valid copy of a, c has an invalid reference.
}
Run Code Online (Sandbox Code Playgroud)


Mar*_*ork 6

在上面的代码中,销毁顺序是明确定义的.
销毁订单与创建订单相反.
创建顺序是成员在类中声明的顺序.
所以在这种情况下:

Default Construction:
  a_:  constructed first using default constructor.
  b_:  constructed using a valid a_ passed to the constructor.

Destruction:
  b_:   destroyed first. The destructor can use the reference to a 
        As long as the object has not been copied (see below)
  a_:   destroyed second.
Run Code Online (Sandbox Code Playgroud)

但是如果使用复制构造函数制作对象的副本,则可能存在问题.

以下复制构造函数由编译器定义:

MyObject::MyObject(MyObject const& copy)
    :a_(copy.a_)
    ,b_(copy.b_)
{}
Run Code Online (Sandbox Code Playgroud)

所以你可能在这里遇到潜在的问题.由于副本将包含一个对象'b_',其中包含从另一个对象复制的引用.如果另一个对象被销毁,则此"b_"将具有无效引用.


chr*_*too 5

a_应该在b_之前构造,并且b_应该在a_之前被破坏,基于你在MyObject中定义它们的顺序.