编译器发出链接错误,需要提供Base纯虚析构函数的定义。
class Base
{
public:
virtual ~Base() = 0;
};
class Derived : public Base
{
public:
virtual ~Derived(){ std::cout << "Derived dtor"; }
};
int main()
{
Derived d;
}
答案 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
是正确的,即使是空的。