13

由于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>(or make_shared<Interface>) 创建,你真的需要一个virtual析构函数吗?无论如何我都会声明它virtual,但我只想知道,因为shared_ptr将始终删除它初始化的类型(除非给出另一个自定义删除器)。

4

1 回答 1

14

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

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

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

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

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

于 2011-07-09T12:38:49.887 回答