【发布时间】:2014-05-17 20:19:01
【问题描述】:
考虑这段代码:
class A {
public:
void fun() {}
};
class B : public A {
public:
void fun() {}
};
int main()
{
A *p = new B;
delete p;
}
类 A 和 B 不是多态的,并且两个类都没有声明析构函数。如果我用g++ -Wall 编译这段代码,GCC 编译器会愉快地编译代码。
但是,如果我在 A 中将 virtual 添加到 void fun(),编译器会发出以下警告:“删除具有非虚拟析构函数的多态类类型‘A’的对象可能会导致未定义的行为”。
我非常清楚使用非虚拟析构函数的危险。但是上面的代码让我想知道两件事:
- 当我根本不使用析构函数时,为什么我需要在基类中编写一个空的虚拟析构函数?
- 如果基类不包含其他虚函数,为什么不需要空的虚析构函数?
编辑
看来我需要澄清困扰我的事情:
上面的代码没有声明任何析构函数。
如果我声明一个虚函数,编译器会抱怨缺少虚析构函数。我的结论:如果类是多态的,如果delete p要正常工作,我需要写一个虚析构函数。
但是如果我没有声明虚函数(如上面的初始示例),编译器不会抱怨缺少虚析构函数。我的结论:如果类不是多态的,我不需要写虚析构函数,delete p 无论如何都会正常工作。
但最后一个结论在我看来直觉上是错误的。这是错的吗?编译器应该在这两种情况下都抱怨吗?
【问题讨论】:
-
这两个问题都断言完全错误的前提,这使得回答起来很尴尬。手头的代码应该简单地写成
B *p = new B;,一切都会好起来的。 -
我在你的代码中没有看到 empty virtual destructor。
-
@oz1cz -
Why do I need to write an empty virtual destructor in the base class when I'm not using destructors at all?所有类都有析构函数。 -
@Kerrek:
A *p = new B; delete p;是完全合法的。问题是它是否适用于非多态类?如果类是多态的,编译器会发出警告,但如果它是非多态的则不会。为什么? -
@Nawaz:你当然不知道。我没有写任何东西,编译器抱怨我没有写任何东西。但是,编译器只在类是多态的时候才会抱怨。为什么?
标签: c++ polymorphism destructor