如果未使用shared_ptr定义虚拟析构函数,有什么好处?

守护进程

当我们将shared_ptr与多态类一起使用时,由于类型为Deleted Deleter,因此不需要虚拟析构函数。

但是在简单的情况下定义析构函数是否有意义。

完全不声明析构函数的好处是什么?

考虑下面的代码

struct Base {                                                                   
  /*virtual*/ ~Base() { std::cout << "Base Dtor" << std::endl; }  
               OR
  /*virtual*/ ~Base() = default;              
  virtual void foo() = 0;                                                       
};                                                                              
                                                                                
struct Derived : Base {                                                         
  ~Derived() { std::cout << "Derived Dtor" << std::endl; }                      
  void foo() override { std::cout << "foo" << std::endl; }                      
};                                                                              
                                                                                
int main() {                                                                    
  std::shared_ptr<Base> ptr = std::make_shared<Derived>();                      
}
重复数据删除器

是的,即使对于多态类型,没有虚拟dtor当然也有好处:

  1. 删除了动态调度,从而可以实现更高效的静态调度甚至是简单的内联。使编译器证明这一点并自行将动态分配减少为静态分配是不平凡的。

  2. 从vtable中删除了deallocating-dtor和just-dtor条目。因此,如果实际上未使用任何一个,则更容易证明,从而有助于消除无效代码。

在宏伟的计划中,这两种效果通常都是微不足道的:

  1. 一种动态调度(最坏的情况)与取消分配的成本相比显得相形见war。

  2. 如果有任何实例,则需要两个(deallocating-dtor和just-dtor)之一,并且由于前者委托后者,所以两者都有少量琐碎的附加指令。这几乎不值得考虑。

另一方面,如果您(或其他人)滑倒(或忽略策略)并编写依赖于此的代码,那么没有虚拟dtor的基础将是非常危险的。未定义的行为很少有趣。
这就是每个人都坚持认为,如果发生任何动态多态性(任何虚函数,dtor,base或具有相同基数的base)的原因,那么dtor也最好是虚拟的!

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

重载 -> shared_ptr<interface> 实例中的箭头运算符,接口中没有纯虚拟析构函数

与“受保护的虚拟析构函数”相比,拥有“受保护的非虚拟析构函数”有什么好处?

从未调用过的shared_ptr对象的析构函数

为什么std :: shared_ptr两次调用我的析构函数?

具有shared_ptr的成员的C ++析构函数顺序

对链接列表使用shared_ptr可以在析构函数中提供stackoverflow

使用shared_ptr时需要实现析构函数,复制构造函数,赋值运算符

如何在具有受保护的析构函数和公共销毁方法的3d派对类上使用shared_ptr

如果A有析构函数,std :: unique_ptr <A>什么时候需要特殊的删除器?

在具有虚拟析构函数的多态继承中使用 enable_shared_from_this

虚拟析构函数,如果在派生类中没有析构函数,会发生什么情况?

为什么要使用虚拟析构函数?

shared_ptr析构函数,复制和不完整类型

不为 shared_ptr 派生类调用析构函数

为什么在使用unique_ptr时没有调用析构函数?

虚拟析构函数= default与空主体的虚拟析构函数之间有什么区别吗?

何时使用虚拟析构函数?

通过类析构函数中的重置成员shared_ptrs解决C ++ 11 shared_ptr循环参考?

如果派生类仅包含自动变量成员,是否有必要使用虚拟析构函数?

有什么方法可以检测是否使用非虚拟基本析构函数正确删除了类?

具有unique_ptr成员和自定义析构函数的对象的向量

了解虚拟析构函数

`虚拟``覆盖`析构函数

为什么非虚拟析构函数没有内存泄漏

具有虚拟析构函数的基类的子类中的默认析构函数

为什么shared_ptr具有移动构造函数

使用BOOST shared_array而不是shared_ptr的好处

与直接通过引用传递相比,通过引用传递给shared_ptr有什么好处?

为什么带有auto_ptr和显式析构函数的struct无法交换