继承的类析构函数

Posted

技术标签:

【中文标题】继承的类析构函数【英文标题】:Inherited class destructor 【发布时间】:2020-05-27 21:23:13 【问题描述】:

我有一个这样的模板类(带有动态数据):

template <class T>
class TemplateClass : public BaseClass 
public:
...
protected:
vector<T> data;
...

它是从 BaseClass 派生的,因为在另一个容器类中,我必须将所有这些模板类都放在同一个向量中:

class Container
public:
...
protected:
vector<BaseClass*> elements;

这样我可以在同一个向量中有不同的类型,并调用 TemplateClass 方法,只需执行 dynamic_cast(ej dynamic_cast&lt;TemplateClass&lt;int&gt;*&gt;(elements[i])-&gt;method(a)("a" 将是一个整数))。 它可以工作(程序运行)但它不能说服我,因为当我销毁容器时,我必须显式调用 TemplateClass 的析构函数,因为 BaseClass 不会破坏数据(向量): delete dynamic_cast&lt;TemplateClass&lt;int&gt;*&gt;(elements[i]) 我想使用 unique_pointer 但我认为它不起作用,因为它不会删除数据(因为将调用 BaseClass 析构函数而不是 TemplateClass 析构函数并且 BaseClass 不能具有此模板向量)。 有没有其他选择?我必须有这个 TemplateClass 向量。 谢谢你

【问题讨论】:

相关,考虑改用std::vector&lt;std::shared_ptr&lt;BaseClass&gt;&gt;,并通过std::make_shared管理其中的元素。然后,您可以在父级销毁时完全放弃手动容器枚举(假设您采用下面的答案并在基础中提供虚拟 dtor,它将为您妥善处理)。 【参考方案1】:

您需要将BaseClass 的析构函数设为virtual 析构函数。

class BaseClass

   virtual ~BaseClass() 
;

随着这一变化,TemplateClass 的析构函数将在您 deleteContainer::elements 中的对象时被调用。在TemplateClass的析构函数中,可以delete动态分配内存。

【讨论】:

但是例如它不能解决 Copy Constructor 的问题,因为它不能被声明为虚拟的。 @pipespups,为了支持这一点,您必须实现一个函数来克隆一个对象。见***.com/questions/24939570/…。 @pipespups • 你需要一个虚拟的clone 函数,因为复制构造函数不能被声明为虚拟的。您需要保护复制构造函数。 @Eljay 构造函数可以保持公开,因为它的含义与 clone 不同。它表明您要基于给定对象创建特定类的新对象。克隆说你想要新的对象不是硬编码的类,而是与给定对象相同的类。保护构造函数可能有意义,但这取决于上下文。 @NO_NAME • 同意,在 OP 帖子中给出的用例中,如果不进行保护,我会在不久的将来看到切片错误。

以上是关于继承的类析构函数的主要内容,如果未能解决你的问题,请参考以下文章

浅谈多态基类析构函数声明为虚函数

在 C++ 继承中,当指向基类的指针对象指向派生类时,不调用派生类析构函数

在 MFC 中调用 EndDialog() 时,类析构函数何时触发?

条款7:为多态基类析构函数声明为virtual

受保护的与私有的析构函数

python 析构函数 实例析构 类析构