如果只有某些派生类是多态的,基类析构函数是否需要是虚拟的?

rui*_*sen 0 c++ polymorphism

我与这个问题有类似的情况,我有两个共享公共接口函数的类,因此我将该函数(示例中的manage_data_in_memory())拉出到这两个类继承的基类中。然而,这两个类在其他方面并不相关,其中一个是多态的,而另一个则不是。也不希望有人声明这个基类的对象,因为它的存在只是为了防止代码重复(有办法强制执行吗?我知道纯虚函数可以防止对象被实例化,但是声明一个虚拟函数在派生类中不执行任何操作的纯虚拟似乎是糟糕的设计)。

在这种情况下,基类析构函数是否需要是虚拟的?这将迫使其他派生类也有一个它不需要的虚拟析构函数。谢谢。

所以现在我的代码格式为

class base  {  // don't instantiate an object of this, is there a way to enforce this?
 public: 
   void manage_data_in_memory();
 protected:
    data;        
 };
    
 class derived : public base
 {
 public:
    void sendData();
 private:
     virtual void sendDataHelper(); // override this in derived classes which need to send custom data in addition to the default data
 };
    
 class derived2 : public base
 { 
  public:
   void do_Z_On_data()
 };
Run Code Online (Sandbox Code Playgroud)

eer*_*ika 5

当且仅当派生类的实例将通过指向基对象的指针被销毁时,基类的析构函数必须是虚拟的。如果在这种情况下析构函数不是虚拟的,那么程序的行为将是未定义的。例子:

struct Base {
    // ...
};
struct Derived : Base {};


std::unique_ptr<Base> ptr = std::make_unique<Derived>();
// Base::~Base must be virtual
Run Code Online (Sandbox Code Playgroud)

通过使用私有继承,可以防止类的用户执行此操作(至少是意外地)。如果析构函数不是虚拟的,那么继承应该是私有的,除非在需要标准布局类的特殊情况下。


这是因为私有继承会使析构函数成为私有的

不,私有继承并不会使析构函数成为私有的。

这会阻止任何人声明 Base 对象?

不,声明 Base 对象不是问题。

私有继承可防止在派生类(及其友元)的成员函数之外从派生指针转换为基指针。无法获取指向派生类基类的指针将阻止用户通过此类指针删除派生对象。