#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); }
};
Has compilation warning
Class '[C@1a9e0f7' has virtual method 'area' but non-virtual destructor
How to understand this warning and how to improve the code?
[EDIT] is this version correct now? (Trying to give answer to elucidate myself with the concept)
#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(){}
};
If a class has a virtual method, that means you want other classes to inherit from it. These classes could be destroyed through a base-class-reference or pointer, but this would only work if the base-class has a virtual destructor. If you have a class that is supposed to be usable polymorphically, it should also be deletable polymorphically.
This question is also answered in depth here. The following is a complete example program that demonstrates the effect:
#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
}
Output:
Destructor of FooBase
Destructor of Bar
Destructor of BarBase
Note that delete bar;
causes both destructors, ~Bar
and ~BarBase
, to be called, while delete foo;
only calls ~FooBase
. The latter is even undefined behavior, so that effect is not guaranteed.