c++ - 如果未使用 shared_ptr 定义虚拟析构函数,是否有任何优势

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

当我们将 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>();                      
}

最佳答案

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

  • 删除了动态调度,允许更有效的静态调度甚至简单的内联。让编译器证明它并自行减少动态到静态的调度并非易事。
  • 从 vtable 中删除了 deallocating-dtor 和 just-dtor 的条目。因此,如果其中任何一个实际上未被使用,则更容易证明,这有助于消除死代码。

  • 在宏伟的计划中,这两种影响通常都是微不足道的:
  • 一个动态调度(在最坏的情况下)与解除分配的成本相比相形见绌。
  • 如果有任何实例,将需要两者之一(deallocating-dtor 和 just-dtor),并且两者都只是微不足道的额外指令,因为前者委托(delegate)给后者。几乎不值得考虑。

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

    关于c++ - 如果未使用 shared_ptr 定义虚拟析构函数,是否有任何优势,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63362025/

    相关文章:

    C++ - 在代码块中使用系统调用(fork、exec、wait 等)

    c++ - 如何设置位图作为子窗口的背景(WIN32)

    c++ - 指向 C++17 中 constexpr 静态成员的 constexpr 指针

    java - 处理大数据集时减少内存流失

    android - 为什么图像由android :src in xml remain stored in heap?设置

    c++ - 抽象和纯虚拟方法

    C++ 使用逻辑而不是手写数据来初始化 STL 容器

    c# - C# 如何为 List<T> 动态分配内存?

    polymorphism - 我可以编写像 C++ 模板函数一样工作 "whenever possible"的 I Julia 方法吗?

    c# - 通过强制转换或鸭式输入不同的对象类型来重用相同的功能