是接口所需的虚析构函数,如果总是将其存储在shared_ptr中

Is a virtual destructor needed for your Interface, if you always store it in a shared_ptr?

本文关键字:存储 shared ptr 如果 接口 析构函数      更新时间:2023-10-16

由于boost::/std::shared_ptr具有类型擦除其删除器的优势,因此您可以做一些很好的事情,例如

#include <memory>
typedef std::shared_ptr<void> gc_ptr;
int main(){
  gc_ptr p1 = new int(42);
  gc_ptr p2 = new float(3.14159);
  gc_ptr p3 = new char('o');
}

由于保存了正确的删除器,这将正确地删除所有指针。

如果你确保你的接口的每个实现总是用shared_ptr<Interface>(或make_shared<Interface>)创建,你真的需要virtual析构函数吗?我将声明它virtual无论如何,但我只是想知道,因为shared_ptr将始终删除它初始化的类型(除非给出另一个自定义删除器)。

对于要派生的类,我仍然会遵循通用规则:

提供公共虚析构函数或受保护的非虚析构函数

原因是您不能控制所有的使用,并且这个简单的规则意味着如果您试图通过层次结构中的错误级别delete,编译器将标记。考虑shared_ptr不保证调用适当的析构函数,只保证调用用作实参的静态类型的析构函数:

base* foo();
shared_ptr<base> p( foo() );

如果base有一个公共非虚析构函数,并且foo返回的类型派生自base,则shared_ptr将无法调用正确的析构函数。如果base的析构函数是虚的,则一切正常,如果它是受保护的,则编译器会告诉您那里有错误。