如果我是对的,默认析构函数总是隐式声明的,除非用户声明它。根据cppreference:
通过指向基类的指针删除对象会调用未定义的行为,除非基类中的析构函数是虚拟的
现在,考虑这个例子:
struct B {};
struct D : B {};
隐式声明的析构函数是B::~B()
虚拟的吗?如果不是,我应该在使用继承时总是声明一个虚拟析构函数吗?
隐式声明的析构函数 B::~B() 是虚拟的吗?
不,根据class.dtor/3:
类 X 的隐式声明的预期析构函数将具有以下形式
~X()
并且,自然地,根据class.dtor/12:
如果一个类有一个带有虚拟析构函数的基类,它的析构函数(无论是用户声明的还是隐式声明的)是虚拟的
如果不是,我应该在使用继承时总是声明一个虚拟析构函数吗?
C++ 核心指南,C.35建议将公共的基类析构函数设为虚拟:
C.35:基类析构函数应该是公共的和虚拟的,或者是受保护的和非虚拟的
原因防止未定义的行为。如果析构函数是公共的,则调用代码可以尝试通过基类指针销毁派生类对象,如果基类的析构函数是非虚拟的,则结果是未定义的。如果析构函数是受保护的,则调用代码不能通过基类指针进行销毁,析构函数不需要是虚拟的;它确实需要受到保护,而不是私有的,以便派生的析构函数可以调用它。通常,基类的编写者不知道销毁时要执行的适当操作。
[...]
注意虚函数定义了派生类的接口,无需查看派生类即可使用该接口。如果接口允许销毁,那么这样做应该是安全的。
[...]
异常我们可以想象一种情况,您可能需要一个受保护的虚拟析构函数:当派生类型的对象(并且只有这样的类型)应该被允许通过指向基类的指针销毁另一个对象(不是它自己)时。不过,我们在实践中还没有看到这样的案例。
执法
- 具有任何虚函数的类应该具有公共和虚拟或受保护和非虚拟的析构函数。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句