Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does 'has virtual method ... but non-virtual destructor' warning mean during C++ compilation?

#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(){}   }; 
like image 200
qazwsx Avatar asked Jan 06 '12 20:01

qazwsx


People also ask

What happens if destructor is not virtual?

Deleting a derived class object using a pointer of base class type that has a non-virtual destructor results in undefined behavior.

Which has virtual members does not have a virtual destructor?

A C++ class containing virtual member functions has a non-virtual destructor. Since this class has virtual member functions, it will be used as a base class.

Is it safe to call virtual methods in constructor and destructor?

Calling virtual functions from a constructor or destructor is considered dangerous most of the times and must be avoided whenever possible. All the C++ implementations need to call the version of the function defined at the level of the hierarchy in the current constructor and not further.

When should you mark a destructor as virtual?

Virtual keyword for destructor is necessary when you want different destructors should follow proper order while objects is being deleted through base class pointer.


1 Answers

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.

like image 87
Björn Pollex Avatar answered Sep 21 '22 05:09

Björn Pollex