这样安全吗?
class Derived: public PublicBase, private PrivateBase
{
...
~Derived()
{
FunctionCall();
}
virtual void FunctionCall()
{
PrivateBase::FunctionCall();
}
}
class PublicBase
{
virtual ~PublicBase(){};
virtual void FunctionCall() = 0;
}
class PrivateBase
{
virtual ~PrivateBase(){};
virtual void FunctionCall()
{
....
}
}
PublicBase* ptrBase = new Derived();
delete ptrBase;
这段代码崩溃了有时IP 地址错误。
每个人都清楚在构造函数上调用虚函数不是一个好主意。
来自类似的文章http://www.artima.com/cppsource/nevercall.html我知道析构函数也是调用虚函数的不太好的地方。
我的问题是“这是真的吗?”我已经用 VS2010 和 VS2005 进行了测试,并调用了 PrivateBase::FunctionCall 。是未定义的行为吗?
我将在这里逆流而行……但首先,我必须假设你的PublicBase
析构函数是虚拟的,否则Derived
析构函数永远不会被调用。
从构造函数/析构函数调用虚函数通常不是一个好主意
原因是这两个操作期间动态调度很奇怪。对象的实际类型changes施工期间及其changes再次在破坏过程中。当执行析构函数时,该对象正是该类型,而不是派生自该类型的类型。动态调度始终有效,但是最终覆盖者虚拟函数的值将根据您在层次结构中的位置而变化。
也就是说,您永远不应该期望对构造函数/析构函数中的虚拟函数的调用以从正在执行的构造函数/析构函数的类型派生的任何类型执行。
But
在您的具体情况下,final覆盖者(至少对于层次结构的这一部分)是above你的水平。而且,你是不使用动态调度根本不。电话PrivateBase::FunctionCall();
是静态解析的,并且实际上相当于对任何非虚拟函数的调用。事实上,该函数是virtual或不不影响本次调用。
So yes尽管您将被迫在代码审查中解释这一点,因为大多数人都了解该规则的口头禅,而不是其原因,但这样做很好。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)