c++ - 在 C++ 编译期间出现 'has virtual method ... but non-virtual destructor' 警告是什么意思?

标签 c++ polymorphism virtual

#include <iostream>
using namespace std;

class CPolygon {
  protected:
    int width, height;
  public:
    virtual int area ()
      { return (0); }
  };

class CRectangle: public CPolygon {
  public:
    int area () { return (width * height); }
  };

有编译警告

Class '[C@1a9e0f7' has virtual method 'area' but non-virtual destructor

如何理解这个警告以及如何改进代码?

[EDIT] 这个版本现在正确吗? (试图给出答案以阐明自己的概念)

#include <iostream>
using namespace std;

class CPolygon {
  protected:
    int width, height;
  public:
    virtual ~CPolygon(){};
    virtual int area ()
      { return (0); }
  };

class CRectangle: public CPolygon {
  public:
    int area () { return (width * height); }
    ~CRectangle(){}
  };

最佳答案

如果一个类有一个虚方法,这意味着你希望其他类继承它。这些类可以通过基类引用或指针来销毁,但这仅在基类具有虚拟析构函数时才有效。如果你有一个应该可以多态使用的类,那么它也应该可以多态删除。

这个问题也有深入解答here .下面是一个完整的示例程序,演示效果:

#include <iostream>

class FooBase {
public:
    ~FooBase() { std::cout << "Destructor of FooBase" << std::endl; }
};

class Foo : public FooBase {
public:
    ~Foo() { std::cout << "Destructor of Foo" << std::endl; }
};

class BarBase {
public:
    virtual ~BarBase() { std::cout << "Destructor of BarBase" << std::endl; }
};

class Bar : public BarBase {
public:
    ~Bar() { std::cout << "Destructor of Bar" << std::endl; }
};

int main() {
    FooBase * foo = new Foo;
    delete foo; // deletes only FooBase-part of Foo-object;

    BarBase * bar = new Bar;
    delete bar; // deletes complete object
}

输出:

Destructor of FooBase
Destructor of Bar
Destructor of BarBase

注意 delete bar; 导致析构函数 ~Bar~BarBase 被调用,而 delete foo; 只调用 ~FooBase。后者甚至是undefined behavior ,所以不能保证效果。

关于c++ - 在 C++ 编译期间出现 'has virtual method ... but non-virtual destructor' 警告是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8764353/

相关文章:

c++ - 当文件以C++打开并且我们开始阅读时,整个文件是从硬盘加载到RAM还是仅逐 block 加载?

c++ - 按属性对包含对象的列表进行排序

c++ - C/C++ : Should serialization methods be class members?

c++ - 另一个与设计相关的 C++ 问题

c++ - (Windows) 何时删除对象和设备上下文?

c# - 如何在托管代码中正确翻译 WH_MOUSE lparam

function - 是否可以在不丢失 ocaml 中参数的多态类型的情况下设置函数的默认值

c++ - 没有虚拟析构函数可能会发生内存泄漏?

c++ - 在派生类 C++ 中避免 "Pure Virtual Function Call"

参数中的 C++ 协方差