如果您始终将它存储在shared_ptr中,那么您的接口是否需要虚拟析构函数?

Xeo*_*Xeo 12 c++ boost shared-ptr virtual-destructor c++11

由于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');
}
Run Code Online (Sandbox Code Playgroud)

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

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

Dav*_*eas 13

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

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

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

base* foo();
shared_ptr<base> p( foo() );
Run Code Online (Sandbox Code Playgroud)

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