我在C++中定义了一个接口,即一个只包含纯虚函数的类.
我想明确禁止接口的用户通过指向接口的指针删除对象,所以我为接口声明了一个受保护的非虚拟析构函数,如:
class ITest{ public: virtual void doSomething() = 0; protected: ~ITest(){} }; void someFunction(ITest * test){ test->doSomething(); // ok // deleting object is not allowed // delete test; }
GNU编译器给我一个警告说:
class'ITest'具有虚函数但非虚析构函数
一旦析构函数受到保护,虚拟或非虚拟有什么区别?
你认为这个警告可以被安全地忽略或沉默吗?
它或多或少是编译器中的一个错误.请注意,在更新版本的编译器中,此警告不会被抛出(至少在4.3中它没有).在您的情况下,让析构函数受到保护并且非虚拟化是完全合法的.
请参阅此处,阅读Herb Sutter关于此主题的精彩文章.来自文章:
准则#4:基类析构函数应该是公共的和虚拟的,或者是受保护的和非虚拟的.
关于这个答案的一些评论与我之前给出的答案有关,这是错误的.
受保护的析构函数意味着它只能从基类调用,而不能通过删除调用.这意味着不能直接删除ITest*,只能派生类.派生类可能需要虚拟析构函数.你的代码完全没有问题.
但是,由于您无法在GCC中本地禁用警告,并且您已经有了vtable,因此您可以考虑将析构函数设置为虚拟.它将花费你4个字节的程序(不是每个类实例),最大.由于您可能已将派生类视为虚拟dtor,因此您可能会发现它不需要任何费用.