如果始终将其存储在shared_ptr中,则接口是否需要虚拟析构函数? [英] Is a virtual destructor needed for your Interface, if you always store it in a shared_ptr?

查看:140
本文介绍了如果始终将其存储在shared_ptr中,则接口是否需要虚拟析构函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于boost::/std::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.

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

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).

推荐答案

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

I would still follow the common rule for classes that are meant to be derived:

提供公共虚拟销毁器或受保护的非虚拟销毁器

Provide either a public virtual destructor or a protected non-virtual destructor

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

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 that shared_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:

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

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

If base has a public non-virtual destructor and foo returns a type that derives from base, then shared_ptr will fail to call the correct destructor. If the destructor of base is virtual, everything will be fine, if it is protected, the compiler will tell you that there is an error there.

这篇关于如果始终将其存储在shared_ptr中,则接口是否需要虚拟析构函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆