2011-08-12 33 views
5
class Base 
{ 
    virtual void foo() = 0; 
    //~Base();  <-- No destructor! 
}; 

显然,Base将被派生。那么,C++是否说编译器生成的Base的析构函数必须是虚拟的?抽象基类的编译器生成的析构函数是虚拟的吗?

谢谢!

+3

不,但我不能给你一个标准的*不*说的东西的参考... –

+2

如果只有编译器才可以在stackoverflow上回答问题;) – MerickOWA

回答

6

不,解析器不会是virtual,除非您将它标记为这样。原因很简单 - 通过指针和通过引用几乎可以进行调用,以及虚拟调用的方式和方式与是否使用new创建对象无关。如果你不用new创建对象,你不需要delete它们,所以你不需要虚拟析构函数。

1

不,dtor不保证是虚拟的。

当声明专门设计为派生类的类时,其明确声明虚拟Dtor的良好实践。这通常是一个彻头彻尾的设计缺陷。事实上,我不能想到这样一种情况,它不是从基础类中遗漏虚拟dtor的设计缺陷。

+2

某些类可以被设计成派生自但不是多态使用(例如'boost :: noncopyable')。在这种情况下,提供虚拟析构函数是没有意义的。 –

+0

@Luc:在这种情况下,保护基类析构函数是个好主意,以防止无效的多态删除。 –

+0

当然,这是真的。我在考虑问题的背景,这是一个ABC。 –

2

它没有。这是接近的证明,析构函数不会自动发虚:

#include <iostream> 

struct BaseBase { 
    ~BaseBase() { 
     std::cout << "~BaseBase\n"; 
    } 
}; 

struct Base : BaseBase 
{ 
    virtual void foo() = 0; 
    //~Base();  <-- No destructor! 
}; 

struct Derived : Base { 
    void foo() { std::cout << "foo\n"; } 
    ~Derived() { 
     std::cout << "~Derived\n"; 
    } 
}; 

int main() { 
    Base *p = new Derived(); 
    delete p; 
} 

这个程序实际上是未定义行为,但我强烈怀疑您的实现不打印“〜派生”。如果Base有一个虚拟析构函数,那么它将不会有未定义的行为,并且会打印“〜Derived”。

当然,它实际上并没有证明有关标准的任何事情。您运行它的任何实现可能都是不合格的。但是一旦你尝试了几次,你会发现无论标准可能会说什么,你都需要指定一个虚拟析构函数。

+0

我在键盘上测试过:http://codepad.org/oMs4Kuye(g ++ 4.1.2),并且不按照预期打印“〜Derived”。无论是在我的MSVC2008。感谢这个例子。 –

1

不。一个班级可以有虚拟成员,可以派生出来,甚至可以用new进行分配,也可以用delete删除,而不需要虚拟析构函数。

如果析构函数未声明为虚拟的,那么非法(UB)要做的是使用指向基址的delete销毁派生实例。

当然,如果您的类是要派生的,没有理由不声明虚拟析构函数。

相关问题