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