我应该使用virtual destructor=default来正确处理具有虚函数的类吗?

4

我忘记了C++。从记忆中,如果我有虚函数,就应该有虚析构函数。所以我写了下面的代码。但是,我会收到关于B析构函数的链接器错误(但不是A)。

正确的解决方案是virtual ~A()=default吗?它似乎有效,但我感觉我漏掉了什么

$ clang++ a.cpp
/usr/bin/ld: /tmp/a-a25aa3.o: in function `B::~B()':
a.cpp:(.text._ZN1BD2Ev[_ZN1BD2Ev]+0x14): undefined reference to `A::~A()'

Source:

class A {
public:
    virtual int test()=0; 
    virtual ~A()=0;
};
class B : public A {
public:
    virtual int BTest()=0;
};

class C : public B {
public:
    int test() override { return 1; }
        int BTest() override { return 2; }
    ~C() override {}    
};

int main() {
    C c;
    c.test();
}

析构函数需要被定义,无论它们是虚拟的、非虚拟的还是纯虚拟的,除非在相对罕见的情况下,即类的实例及其任何派生类的实例都没有被实例化。原因在于销毁派生类实例时会调用基类的析构函数。这一点与该类是否有其他虚拟函数无关。 - Peter
1个回答

5
尽管纯虚析构函数
virtual ~A() = 0;

如果要符合C++的法律标准,您需要为此编写一个函数体,因为析构函数不会被覆盖。 (如果不这样做,链接器将会失败,正如您所观察到的那样。)

自从C++11以来,使您的类具有多态性的最简单方法是使默认析构函数成为虚拟,这可以通过以下方式实现:

virtual ~A() = default;

是的,你提出的解决方案是正确的。


析构函数不能重载彼此吗?我猜这就是解决方案的原因。已接受。 - Pac
@Pac 默认情况下不行,你必须显式地将它们设置为virtual。对于_纯虚拟_接口来说这很重要:它们唯一真正需要的函数是一个虚拟析构函数。 - πάντα ῥεῖ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接