Base dtor应该有定义吗?

时间:2010-12-09 09:29:29

标签: c++

编译器发出链接错误,需要提供Base纯虚析构函数的定义。

class Base
{
public:
    virtual ~Base() = 0;
};

class Derived : public Base
{
public:
    virtual ~Derived(){ std::cout << "Derived dtor"; }
};

int main()
{
       Derived d;
}

3 个答案:

答案 0 :(得分:5)

只为它提供一个空实现(在类定义之外):

Base::~Base() { }

纯粹虚拟只意味着必须覆盖任何具体派生类中的成员函数;这并不意味着它不能拥有一个身体。对于析构函数,必须提供一个正文,而析构函数是纯虚拟的还是非虚拟的,因为在销毁对象时编译器会调用它。

为了清楚起见,您必须提供一个实现。是否空无由你自己决定。这是因为每当您尝试销毁Base实例时,编译器都会生成调用析构函数的代码。您可以声明一个普通的虚拟Base:

virtual ~Base();

永远不要定义它。只要您永远不会破坏Base的实例(可疑的行为,但它会起作用),这将没有问题。但是,在您的情况下,Base有一个派生类型,它在自己的析构函数中调用Base类的析构函数。这就是你的链接器错误的来源。

答案 1 :(得分:3)

由于Derived继承Base,因此销毁Derived对象将首先调用Derived::~Derived然后调用Base::~Base(编译器会为您执行此操作 - 无论您喜欢是不是。)

因此,您必须为Base::~Base提供实施。请注意,这并不是特别奇怪。纯虚函数可以具有实现。 “纯虚拟”只意味着该类无法实例化。

答案 2 :(得分:3)

是。来自Base::~Base的内容是Derived::~Derived的非虚拟调用。因此,编译器抱怨必须定义Base::~Base是正确的,即使是空的。