#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 you can appreciate this warning and just how to enhance the code?

[EDIT] is version correct now? (Attempting to give response to elucidate myself using 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 your class includes a virtual method, which means you would like other classes to inherit from this. These classes might be destroyed via a base-class-reference or pointer, but this could only work when the base-class includes a virtual destructor. For those who have a category that's said to be functional polymorphically, it ought to be deletable polymorphically.

This can also be clarified thorough here. This is an entire example program that demonstrates the result:

#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

Observe that delete bar; causes both destructors, ~Bar and ~BarBase, to become known as, while delete foo; only calls ~FooBase. The second is even undefined behavior, to ensure that effect isn't guaranteed.

this means you'll need a virtual destructor on the base class with virtual techniques.

struct Foo {
  virtual ~Foo() {}
  virtual void bar() = 0;
};

Departing them back is can result in undefined behavior, usually turns up like a memory leak in tools like valgrind.

It basically implies that a code like

CPolygon* p = new CRectangle;
delete p;

... or whatever wrapping into whatever wise pointer, will basically not behave properly since CPolygon isn't polymorphic on deletion, and also the CRectange part won't be destroyed correctly.

If you are not likely to remove CRectangle and CPolygon polymorphicaly, that warning isn't significant.