类拥有虚函数和可访问的非虚析构函数

23

我有两个类:

class A {
public:
    virtual void somefunction() = 0;
};

class B : public A {
public:
    B();
    ~B();
    void somefunction();
};

B::B() {}

void B::somefunction() {
    //  some code
}

但使用 g++ 时,我会收到错误消息:

class A has virtual functions and accessible non-virtual destructor
class B has virtual functions and accessible non-virtual destructor

我不知道这个错误是什么意思...在一些博客上读到它是编译器警告。我该如何解决这个问题?

4个回答

29

这是因为你的基类 A 没有虚拟析构函数。例如,如果你有以下代码:

int main()
{
    A* a = new B;
    delete a;
}

那么,如果delete a调用的是B的析构函数,因为A的析构函数不是虚拟的,所以无法调用B的析构函数。这会导致B的所有资源泄漏。你可以在这里阅读更多有关虚拟析构函数的信息。

在你的基类中添加一个虚拟析构函数,问题就应该解决了。

class A
{
public:  
    virtual void somefunction() = 0;
    virtual ~A() = default;
}

2
@SPB 这意味着它找不到您析构函数的实现。如果您没有要销毁的内容,请编写一个简单的析构函数。A::~A() { } 就可以了。 - zneak

7

提供A类:

virtual ~A() { }

那样,像B这样的派生类在通过删除时仍将调用它们的自定义析构函数。

4

按照经验法则(在我看来),或简而言之,基类中的析构函数必须是公共且虚拟的,或者是受保护的非虚拟的,以防止内存泄漏。通过这样做,派生类的析构函数将被调用,从而防止了每当删除持有派生地址/引用的基本指针/引用时发生内存泄漏


虽然我同意这一点。但不幸的是,GCC的警告并不赞同。也就是说,当基类中的析构函数被声明为“protected”时,它仍会发出此警告。 - Giel

2
如果一个类有虚函数,那么它的析构函数也应该是虚函数。你的类有一个可访问的析构函数,但它不是虚函数。

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