base class 的子 classes 中的默认析构函数带有虚拟析构函数

Default destructor in subclasses of base class with a virtual destructor

我有一个带有虚拟析构函数的基 class AA 有使用默认析构函数的后代 BC。通过指向 A 的指针删除 C 的对象是否安全?

更具体地说,考虑这个示例代码:

class A {
 public:
      A(){};
      virtual ~A() {/* code here */};
 };
 class B: public A {
      B() {/* code....*/};
      /* NO DESTRUCTOR SPECIFIED */
   };
 class C: public B {/*same as above, no destructor */};
 class D: public B {/* same as above, no destructor*/}

要成为 运行 的代码看起来像这样:

A* getAPointer(void); /* a function returning a C or a D*/
A* aptr=getAPointer();
/* aptr is declared as A*, but points to either an object of class C 
  or class D*/
delete aptr;

delete aptr安全吗?它做了正确的事情吗:如果 aptr 指向 class C 的对象,aptr 首先调用 C 的析构函数,然后 B 的析构函数,最后是 A 的析构函数 ?

Is it safe to delete an object of C through a pointer to A?

是的。由于 A 的析构函数是 virtual,因此将调用 C 的析构函数。这完全是由于 动态调度 的工作原理。

Is it safe to delete an object of C through a pointer to A?

是的,它是完全安全的,因为 类 BCD 中的所有析构函数都是隐式虚拟的。

发件人:

15.4 Destructors [class.dtor]

10 A destructor can be declared virtual (13.3) or pure virtual (13.4); if any objects of that class or any derived class are created in the program, the destructor shall be defined. If a class has a base class with a virtual destructor, its destructor (whether user- or implicitly-declared) is virtual.

由于A有虚析构函数,那么BCD分别有虚析构函数和:

delete aptr;

工作正常。

是的,很安全。将 virtual 添加到派生 类 的析构函数中是多余的。

考虑该机制的工作原理。当使用 delete 时,运行时需要知道销毁链应该从哪个析构函数开始。如果 delete 操作数的静态类型有一个 virtual 析构函数,那么这已经足以让运行时知道它必须采取额外的麻烦并检查动态类型。

在你的例子中,它发现动态类型是C,所以调用了C::~CC::~C 自动导致 B::~B 而那个自动导致 A::~A.

要求 C(或 B)的析构函数为 virtual 是没有意义的。毕竟,如果 A::~Avirtual,运行时无论如何都必须找出动态 C 类型。那时,它并不关心 C::~C 是否为 virtual。这会有什么不同?