【问题标题】:Is there any advantage if virtual destructor is not defined with shared_ptr如果未使用 shared_ptr 定义虚拟析构函数,是否有任何优势
【发布时间】:2020-12-01 08:18:55
【问题描述】:

当我们将 shared_ptr 与多态类一起使用时,由于类型擦除删除器,我们不需要虚拟析构函数。

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

根本不声明析构函数有什么好处?

考虑下面的代码

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>();                      
}

【问题讨论】:

  • @Story 真的吗? OP 没有问他是否必须有一个虚拟 dtor,也没有问他是否应该有一个虚拟 dtor。相反,他问没有虚拟 dtor 是否有任何优势。而另一个帖子没有问这个,也没有唯一的答案刷在上面。
  • TBH,我仍然会宣布析构函数 virtual 出于偏执。通过代码库远角的一行上的接口指针意外删除太容易了。虚拟析构函数的大小和性能成本不太可能很高,它为所有删除设置了一个广泛的安全网。权衡是值得的,IMO。
  • 分析会告诉你 cdhowie 的假设是否被证明是错误的。它可能不会。您可以改进一些更大的东西。

标签: c++ memory polymorphism shared-ptr virtual-destructor


【解决方案1】:

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

  1. 删除了动态调度,允许更有效的静态调度甚至简单的内联。让编译器证明这一点并自行将动态调度减少为静态调度并非易事。

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

从总体上看,这两种影响通常都是微不足道的:

  1. 一个动态调度(在最坏的情况下)与解除分配的成本相比相形见绌。

  2. 如果有任何实例,将需要两者中的一个(deallocating-dtor 和 just-dtor),并且两者兼有只是微不足道的额外指令,因为前者委托给后者。这几乎不值得考虑。

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

【讨论】:

    猜你喜欢
    • 2021-08-22
    • 2015-08-22
    • 2011-08-27
    • 1970-01-01
    • 1970-01-01
    • 2012-04-13
    • 2017-01-27
    • 2011-10-01
    相关资源
    最近更新 更多