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

后端 未结 3 1541
孤城傲影
孤城傲影 2020-12-13 06:05
#include 
using namespace std;

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

cl         


        
相关标签:
3条回答
  • 2020-12-13 06:26

    it means you need a virtual destructor on a base class with virtual methods.

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

    Leaving it off is can lead to undefined behavior, usually shows up as a memory leak in tools like valgrind.

    0 讨论(0)
  • 2020-12-13 06:30

    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.

    0 讨论(0)
  • 2020-12-13 06:50

    It merely means that a code like

    CPolygon* p = new CRectangle;
    delete p;
    

    ... or whatever wrapping into whatever smart pointer, will essentially not behave correctly since CPolygon is not polymorphic on deletion, and the CRectange part will not be destroyed properly.

    If you're not going to delete CRectangle and CPolygon polymorphicaly, that warning is not meaningful.

    0 讨论(0)
提交回复
热议问题