Search code examples
c++eclipsemethodsvirtual

Class has virtual method but non virtual destructor C++


Possible Duplicate:
GNU compiler warning “class has virtual functions but non-virtual destructor”

I am writing an interface for two classes and I get the warning in the title. Here's the code:

class GenericSymbolGenerator {
   protected:                     // <== ok 
    ~GenericSymbolGenerator(void) {}

   public:
    virtual GenericSymbolTableCollection* generateSymbolTableCollection(GenericSymbolTableCollection *gst) = 0;
    GenericSymbolGenerator(void) {}
    // ~GenericSymbolGenerator(void) {} // <== warning if used
};

class PascalPredefinedSymbolGenerator : public GenericSymbolGenerator {
   protected:
    ~PascalPredefinedSymbolGenerator(void) {} // <== ok

   public:
    GenericSymbolTableCollection* generateSymbolTableCollection(GenericSymbolTableCollection *pst); // initializes *pst
    PascalPredefinedSymbolGenerator(void) {}
    // ~PascalPredefinedSymbolGenerator(void) {} <== warning if used
};

class PascalSymbolGenerator : public GenericSymbolGenerator {
    protected:
         ~PascalSymbolGenerator(void) {} // <== ok

    public:
     GenericSymbolTableCollection* generateSymbolTableCollection(GenericSymbolTableCollection *st); // initializes st
     PascalSymbolGenerator(void) {}
     // ~PascalSymbolGenerator(void) {} // <== warning if used
};

As long as the constructor/destructor is void there is no issue in declaring the destructor as protected. The problem arises when the class makes use of the heap(the destructor being declared as protected there is no way of freeing the class from the "outside" making the object "indestructible"). Is there a more convenient approach(aside from going public all the way)?


Solution

  • Classes for use as polymorphic bases should have either a virtual destructor or a protected destructor.

    The reason is that if you have a public, non-virtual destructor, then pretty much any use of it by an external user of the class is unsafe. For example:

    GenericSymbolGenerator *ptr = new PascalPredefinedSymbolGenerator();
    delete ptr; // behavior is undefined, we tried to call the base class destructor
    

    By marking the destructor protected, you prevent the user from deleting a PascalPredefinedSymbolGenerator object via the base class. By making the destructor public and virtual, you get defined behavior when the user deletes through the base class. So pick one of those options.