当我们将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当然也有好处:

  • 删除了动态调度,从而可以提高静态调度的效率,甚至可以轻松地进行内联。使编译器证明这一点并自行将动态分配减少为静态分配是不平凡的。
  • 从vtable中删除了deallocating-dtor和just-dtor条目。因此,如果实际上未使用任何一个,则更容易证明,从而有助于消除无效代码。

  • 在宏伟的计划中,这两种效果通常都是微不足道的:
  • 动态分配(在最坏的情况下)与取消分配的成本相比显得相形见war。
  • 如果存在任何实例,则需要两个(deallocating-dtor和just-dtor)中的一个,并且由于前者委托(delegate)后者,所以两者都有少量琐碎的附加指令。这几乎不值得考虑。

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

    10-04 14:46