类有虚方法但非虚析构函数C++

Seb*_*ebi 7 c++ eclipse methods virtual

可能重复:
GNU编译器警告"类具有虚函数但非虚析构函数"

我正在为两个类编写一个接口,我在标题中收到警告.这是代码:

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
};
Run Code Online (Sandbox Code Playgroud)

只要构造函数/析构函数为void,将析构函数声明为受保护就没有问题.当类使用堆时(析构函数被声明为受保护,无法将类从"外部"释放出来,使对象"不可破坏"),就会出现问题.有没有更方便的方法(除了一路上市)?

Ste*_*sop 11

用作多态基的类应该具有虚析构函数或受保护的析构函数.

原因是如果你有一个公共的,非虚拟的析构函数,那么该类的外部用户对它的任何使用都是不安全的.例如:

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

通过标记析构函数protected,可以防止用户PascalPredefinedSymbolGenerator通过基类删除对象.通过使析构函数公开virtual,当用户通过基类删除时,您将获得定义的行为.所以选择其中一个选项.

  • @Sebi:不,它只能防止它们通过指针到基地被删除.它们仍然可以通过指向派生的方式删除.如果你的派生类对用户是隐藏的,那些只是调用一些工厂函数给他们一个智能指针,它知道要删除它的类型 - 然后你就会使用`protected`析构函数. (5认同)