#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
如何理解此警告以及如何改进代码?
[编辑]这个版本现在正确吗? (试图回答用这个概念来阐明自己)
#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(){}
};
答案 0 :(得分:77)
如果一个类有一个虚方法,那就意味着你希望其他类继承它。这些类可以通过基类引用或指针销毁,但这只有在基类具有虚拟析构函数时才有效。如果你有一个应该是多态的类,那么它也应该是多态的可删除的。
这个问题也得到了深入的回答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,因此无法保证效果。
答案 1 :(得分:14)
这意味着您需要使用虚方法在基类上使用虚拟析构函数。
struct Foo {
virtual ~Foo() {}
virtual void bar() = 0;
};
将其关闭 会导致未定义的行为,通常会在valgrind等工具中显示为内存泄漏。
答案 2 :(得分:2)
它仅仅意味着像
这样的代码CPolygon* p = new CRectangle;
delete p;
...或任何包装成智能指针的东西, 因为CPolygon在删除时不是多态的,并且CRectange部分不会被正确销毁。
如果您不打算删除CRectangle和CPolygon的多态,那么该警告没有意义。