如果未使用 shared_ptr 定义虚拟析构函数,是否有任何优势
Is there any advantage if virtual destructor is not defined with shared_ptr
当我们将 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 当然也有好处:
删除了动态调度,允许更有效的静态调度甚至更容易的内联。让编译器自行证明并减少动态到静态分派是 non-trivial.
从 vtable 中删除了 deallocating-dtor 和 just-dtor 的条目。因此,如果其中任何一个实际上未被使用,那么证明起来要容易得多,从而有助于消除无用代码。
在宏伟的计划中,这两种影响通常都是微不足道的:
与解除分配的成本相比,一次动态调度(在最坏的情况下)相形见绌。
如果有任何实例,将需要两者之一(deallocating-dtor 和 just-dtor),并且与前代表一样,同时拥有两者只是微不足道的额外指令到后者。几乎不值得考虑。
另一方面,如果您(或其他人)失误(或忽略策略)并编写依赖于它的代码,则没有带有虚拟 dtor 的基础可能会非常危险。未定义的行为很少有趣。
这就是为什么每个人总是坚持如果发生任何动态多态性(任何虚函数、dtor、base 或具有相同的 base),那么 dtor 最好也是虚拟的!
当我们将 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 当然也有好处:
删除了动态调度,允许更有效的静态调度甚至更容易的内联。让编译器自行证明并减少动态到静态分派是 non-trivial.
从 vtable 中删除了 deallocating-dtor 和 just-dtor 的条目。因此,如果其中任何一个实际上未被使用,那么证明起来要容易得多,从而有助于消除无用代码。
在宏伟的计划中,这两种影响通常都是微不足道的:
与解除分配的成本相比,一次动态调度(在最坏的情况下)相形见绌。
如果有任何实例,将需要两者之一(deallocating-dtor 和 just-dtor),并且与前代表一样,同时拥有两者只是微不足道的额外指令到后者。几乎不值得考虑。
另一方面,如果您(或其他人)失误(或忽略策略)并编写依赖于它的代码,则没有带有虚拟 dtor 的基础可能会非常危险。未定义的行为很少有趣。
这就是为什么每个人总是坚持如果发生任何动态多态性(任何虚函数、dtor、base 或具有相同的 base),那么 dtor 最好也是虚拟的!