如果您总是将其存储在shared_ptr中,您的接口是否需要虚拟析构函数?
由于 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
(或 make_shared
)创建的,那么您真的需要一个 virtual
代码> 析构函数?无论如何,我都会声明它是虚拟的,但我只是想知道,因为shared_ptr将始终删除它初始化的类型(除非给出另一个自定义删除器)。
Since boost::/std::shared_ptr
have the advantage of type-erasing their deleter, you can do nice things like
#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');
}
And this will correctly delete all pointer thanks to the correct deleter being saved.
If you ensure that every implementation of your interface always gets created with shared_ptr<Interface>
(or make_shared<Interface>
), do you actually need a virtual
destructor? I would declare it virtual
anyways, but I just want to know, since shared_ptr
will always delete the type it was initialized with (unless another custom deleter is given).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我仍然会遵循派生类的通用规则:
原因是您无法控制所有用途,并且这个简单的规则意味着如果您尝试通过错误的方式
删除
,编译器将进行标记层次结构中的级别。考虑到shared_ptr
不保证它将调用适当的析构函数,仅保证它将调用用作参数的静态类型的析构函数:如果
base
有一个 public非虚拟析构函数并且foo
返回派生自base
的类型,则shared_ptr
将无法调用正确的析构函数。如果base
的析构函数是virtual的,那么一切都会好起来的,如果它是protected的,编译器会告诉你那里有错误。I would still follow the common rule for classes that are meant to be derived:
The reason is that you cannot control all of the uses, and that simple rule means that the compiler will flag if you try to
delete
through the wrong level in the hierarchy. Consider thatshared_ptr
does not guarantee that it will call the appropriate destructor, only that it will call the destructor of the static type that was used as argument:If
base
has a public non-virtual destructor andfoo
returns a type that derives frombase
, thenshared_ptr
will fail to call the correct destructor. If the destructor ofbase
is virtual, everything will be fine, if it is protected, the compiler will tell you that there is an error there.