Sha*_*ain 20 c++ language-design virtual-destructor
据我所知,任何指定具有子类的类都应该使用虚拟析构函数声明,因此在通过指针访问类实例时可以正确销毁它们.
但为什么甚至可以用非虚析构函数声明这样的类?我相信编译器可以决定何时使用虚拟析构函数.那么,它是一个C++设计监督,还是我错过了什么?
Mat*_* M. 19
有没有具体的理由使用非虚拟析构函数?
是的,有.
主要是,它归结为性能.无法内联虚函数,而必须首先确定要调用的正确函数(这需要运行时信息),然后调用该函数.
在性能敏感的代码中,无代码和"简单"函数调用之间的区别可能会有所不同.与许多语言不同,C++并不认为这种差异是微不足道的.
但为什么甚至可以用非虚析构函数声明这样的类?
因为很难知道(对于编译器)类是否需要虚拟析构函数.
在以下情况下需要虚拟析构函数:
delete指针当编译器看到类定义时:
delete在这个课上调用很多人以为多态性需要newing实例,这只是纯粹缺乏想象力:
class Base { public: virtual void foo() const = 0; protected: ~Base() {} };
class Derived: public Base {
public: virtual void foo() const { std::cout << "Hello, World!\n"; }
};
void print(Base const& b) { b.foo(); }
int main() {
Derived d;
print(d);
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,不需要为虚拟析构函数付费,因为在销毁时没有涉及多态性.
最后,这是一个哲学问题.在可行的情况下,C++默认选择性能和最小服务(主要的例外是RTTI).
关于警告.可以利用两个警告来发现问题:
-Wnon-virtual-dtor(gcc,Clang):只要具有虚函数的类没有声明虚析构函数,就会发出警告,除非生成基类中的析构函数protected.这是一个悲观的警告,但至少你不会错过任何东西.
-Wdelete-non-virtual-dtor(Clang,移植到gcc):警告只要delete在指向具有虚函数但没有虚析构函数的类的指针上调用,除非标记了类final.它的误报率为0%,但警告"迟到"(可能是几次).
| 归档时间: |
|
| 查看次数: |
3135 次 |
| 最近记录: |