在我的应用程序中,我曾经有一个unique_ptr<parent> _member
作为自定义类的成员。代码工作正常。但是,当我最近尝试创建另一个继承自parent
类的类,并在构造函数中使用_member
初始化_member = unique_ptr<child>(new child())
时,我意识到当自定义类被销毁时,析构函数为_member
只调用父析构函数,但现在调用子析构函数。
这种行为对我有意义。因为afterall _member
属于unique_ptr<parent>
类型。但是我想知道在给出_member
时调用子析构函数的选项是什么。
答案 0 :(得分:3)
这种行为没有意义。如果孩子的析构函数需要释放内存,并且没有调用它,你就会泄漏内存。
父需要有一个虚析构函数,以便在通过指向父节点的指针删除它们时允许调用派生类的析构函数。
经验法则:如果基类至少有一个虚函数,它应该有一个虚析构函数。
答案 1 :(得分:2)
除了尼尔的好答案之外,您还可以选择另一条路线。
如果您使用std::shared_ptr
代替std::unique_ptr
,您将获得std::shared_ptr
类型删除功能的好处。让我们看一个例子:
#include <memory>
#include <iostream>
struct X {
~X() {
std::cout << __PRETTY_FUNCTION__ << "\n";
}
};
struct Y : X {
~Y() {
std::cout << __PRETTY_FUNCTION__ << "\n";
}
};
int main() {
std::shared_ptr<X> obj = std::make_shared<Y>();
}
此代码在运行时将输出:
Y::~Y()
X::~X()
答案 2 :(得分:0)
我会将父类析构函数设为虚拟。如果你有一个用例需要一个没有虚函数的类被正确销毁而且你不想使用std::shared_ptr
进行类型擦除的销毁功能,你可以用{实现同样的功能{1}}和自定义删除器:
unique_ptr