继承与析构 - 理论问题 - C++

1 c++ inheritance destructor exception

class A
{
    public:
         virtual void f(){ printf("A.f "); }
         ~A(){ f(); }
};

class B : public A
{
    A a;

    public:
         void f(){ printf("B.f "); }
         B(){ throw -1; }
        ~B(){ f(); }
};

int main()
{
    try{ B b; }
    catch(...){ printf("Exc");}
}
Run Code Online (Sandbox Code Playgroud)

所以这就是我看到它的方式.在try块内部,构建时没有任何东西被打印出来B b;.块结束.我认为编译器首先破坏了A a;成员.所以A.f()会被打印出来.这是否意味着class B实例的破坏已经完成?之后,编译器会简单地调用~A()(破坏基类)吗?

我认为我应该得到A.f(),然后B.f()(破坏B类实例)然后A.f()再次(基类的析构函数).编译这个让我想一点.当然,正在打印Exc.我经历了几个主题,但没有找到任何东西.

编辑:Dev-C++(GCC 3.4.2)的输出是

Af Af Exc

wkl*_*wkl 10

你真的有两个A对象.

  1. B继承自A,因此A在B之前首先实例化基类对象.
  2. A创建另一个实例,因为您有一个类型的成员字段A作为其一部分B.

创建时B b,可以创建基类A,也可以创建实例A a.

但是,然后在B构造函数中抛出异常,这样就可以破坏该点上所有完全构造的对象.

  • ~A()在实例上调用A a.
  • ~A()在基类上调用A.

这可以解释为什么你得到A.f A.f Exc.

B析构函数不会被调用,因为B它没有完全构造,因为它的构造函数没有成功完成.