base class 的子 classes 中的默认析构函数带有虚拟析构函数
Default destructor in subclasses of base class with a virtual destructor
我有一个带有虚拟析构函数的基 class A
。 A
有使用默认析构函数的后代 B
和 C
。通过指向 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?
是的,它是完全安全的,因为 类 B
、C
和 D
中的所有析构函数都是隐式虚拟的。
发件人:
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
有虚析构函数,那么B
和C
、D
分别有虚析构函数和:
delete aptr;
工作正常。
是的,很安全。将 virtual
添加到派生 类 的析构函数中是多余的。
考虑该机制的工作原理。当使用 delete
时,运行时需要知道销毁链应该从哪个析构函数开始。如果 delete
操作数的静态类型有一个 virtual
析构函数,那么这已经足以让运行时知道它必须采取额外的麻烦并检查动态类型。
在你的例子中,它发现动态类型是C
,所以调用了C::~C
。 C::~C
自动导致 B::~B
而那个自动导致 A::~A
.
要求 C
(或 B
)的析构函数为 virtual
是没有意义的。毕竟,如果 A::~A
是 virtual
,运行时无论如何都必须找出动态 C
类型。那时,它并不关心 C::~C
是否为 virtual
。这会有什么不同?
我有一个带有虚拟析构函数的基 class A
。 A
有使用默认析构函数的后代 B
和 C
。通过指向 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 toA
?
是的。由于 A
的析构函数是 virtual,因此将调用 C
的析构函数。这完全是由于 动态调度 的工作原理。
Is it safe to delete an object of C through a pointer to A?
是的,它是完全安全的,因为 类 B
、C
和 D
中的所有析构函数都是隐式虚拟的。
发件人:
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
有虚析构函数,那么B
和C
、D
分别有虚析构函数和:
delete aptr;
工作正常。
是的,很安全。将 virtual
添加到派生 类 的析构函数中是多余的。
考虑该机制的工作原理。当使用 delete
时,运行时需要知道销毁链应该从哪个析构函数开始。如果 delete
操作数的静态类型有一个 virtual
析构函数,那么这已经足以让运行时知道它必须采取额外的麻烦并检查动态类型。
在你的例子中,它发现动态类型是C
,所以调用了C::~C
。 C::~C
自动导致 B::~B
而那个自动导致 A::~A
.
要求 C
(或 B
)的析构函数为 virtual
是没有意义的。毕竟,如果 A::~A
是 virtual
,运行时无论如何都必须找出动态 C
类型。那时,它并不关心 C::~C
是否为 virtual
。这会有什么不同?