继承的类析构函数
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<TemplateClass<int>*>(elements[i])->method(a)
("a" 将是一个整数))。
它可以工作(程序运行)但它不能说服我,因为当我销毁容器时,我必须显式调用 TemplateClass 的析构函数,因为 BaseClass 不会破坏数据(向量):
delete dynamic_cast<TemplateClass<int>*>(elements[i])
我想使用 unique_pointer 但我认为它不起作用,因为它不会删除数据(因为将调用 BaseClass 析构函数而不是 TemplateClass 析构函数并且 BaseClass 不能具有此模板向量)。
有没有其他选择?我必须有这个 TemplateClass 向量。
谢谢你
【问题讨论】:
相关,考虑改用std::vector<std::shared_ptr<BaseClass>>
,并通过std::make_shared
管理其中的元素。然后,您可以在父级销毁时完全放弃手动容器枚举(假设您采用下面的答案并在基础中提供虚拟 dtor,它将为您妥善处理)。
【参考方案1】:
您需要将BaseClass
的析构函数设为virtual
析构函数。
class BaseClass
virtual ~BaseClass()
;
随着这一变化,TemplateClass
的析构函数将在您 delete
Container::elements
中的对象时被调用。在TemplateClass
的析构函数中,可以delete
动态分配内存。
【讨论】:
但是例如它不能解决 Copy Constructor 的问题,因为它不能被声明为虚拟的。 @pipespups,为了支持这一点,您必须实现一个函数来克隆一个对象。见***.com/questions/24939570/…。 @pipespups • 你需要一个虚拟的clone
函数,因为复制构造函数不能被声明为虚拟的。您需要保护复制构造函数。
@Eljay 构造函数可以保持公开,因为它的含义与 clone
不同。它表明您要基于给定对象创建特定类的新对象。克隆说你想要新的对象不是硬编码的类,而是与给定对象相同的类。保护构造函数可能有意义,但这取决于上下文。
@NO_NAME • 同意,在 OP 帖子中给出的用例中,如果不进行保护,我会在不久的将来看到切片错误。以上是关于继承的类析构函数的主要内容,如果未能解决你的问题,请参考以下文章
在 C++ 继承中,当指向基类的指针对象指向派生类时,不调用派生类析构函数