Class has virtual method but non virtual destructor C++
Possible Duplicate:
GNU compiler warning “class has virtual functions but non-virtual destructor”
我正在为两个类编写接口,标题中有警告。代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | 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 }; |
只要构造函数/析构函数是空的,就不会将析构函数声明为受保护。当类使用堆时会出现问题(析构函数被声明为受保护,无法将类从"外部"释放出来,从而使对象"不可破坏")。有没有更方便的方法(除了一路公开)?
用作多态基的类应具有虚拟析构函数或受保护的析构函数。
原因是,如果您有一个公共的、非虚拟的析构函数,那么类的外部用户对它的任何使用都是不安全的。例如:
1 2 | GenericSymbolGenerator *ptr = new PascalPredefinedSymbolGenerator(); delete ptr; // behavior is undefined, we tried to call the base class destructor |
通过标记析构函数
我认为编译器警告您有关基类中的非虚拟析构函数是正确的。您已经创建了一个明确打算作为继承层次结构根的类,但是通过使基类析构函数非虚拟化,您已经破坏了通过指向基类的指针删除对象的能力(因为所有将执行的都是基类的析构函数,因此不会采取派生类特定的操作)。在C++中,这是一个非常糟糕的想法,因为当涉及到这个对象层次结构时,基本上打破了多态性的实现。
正如您在注释中所提到的,您的意图是使用GenericSymbolGenerator作为接口,并强制用户实例化和使用包含实际实现代码的派生类。在C++中声明接口的一种规范方式是在接口上声明至少一个函数作为纯虚函数。这将禁止您实例化基类,但仍然创建可实例化的派生类。您已经通过将
另外,作为旁白,默认构造函数和析构函数的规范签名通常是在不使用"void"作为参数的情况下编写的,只需使用空括号即可。