The class has a virtual method, but not a C ++ virtual destructor

Possible duplicate:
GNU compiler warning "class has virtual functions, but not virtual destructor"

I am writing an interface for two classes and I am getting a warning in the header. Here is 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 invalid, there is no problem declaring the destructor as protected. The problem arises when the class uses heap (the destructor is declared protected, so there is no way to free the class from "outside", which makes the object "indestructible"). Is there a more convenient approach (not to mention public access)?

+6
source share
2 answers

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

The reason is that if you have an open, non-virtual destructor, then almost any use by this external user of this class is unsafe. For instance:

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

By noting the protected destructor, you will prevent the user from deleting the PascalPredefinedSymbolGenerator object through the base class. By doing a public destructor and virtual , you get certain behavior when the user deletes it through the base class. Therefore, choose one of these options.

+10
source

I would say that the compiler is right to warn you about a non-virtual destructor in the base class. You created a class that is explicitly intended as the root of the inheritance hierarchy, but by creating a non-virtual destructor class, you violated your ability to delete an object with a pointer to the base class (since everything that is executed is a destructor of the base class, so no derived classes will be executed ) This is considered a very bad idea in C ++, since you are significantly disrupting the implementation of polymorphism when it comes to this hierarchy of objects.

As you mentioned in your comments, your goal is to use the GenericSymbolGenerator as an interface and force the user to instantiate and use derived classes containing the actual implementation code. The canonical way to declare an interface in C ++ is to declare at least one interface function as a pure virtual function. This prevents you from creating an instance of the base class, but at the same time creating instances of derived classes. You already did this by declaring generateSymbolTableCollection() pure virtual function in the base class. So all you have to do is make a virtual virtual destructor, since it really has to be virtual in this particular scenario.

Also, as an aside, canonical signatures for the default constructor and destructor are usually written without using "void" as a parameter, just use empty brackets instead.

+2
source

Source: https://habr.com/ru/post/926623/


All Articles