gpt4 book ai didi

c++ - 从析构函数调用虚函数

转载 作者:IT老高 更新时间:2023-10-28 12:34:05 24 4
gpt4 key购买 nike

这样安全吗?

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 析构函数将永远不会是调用。

从构造函数/析构函数调用虚函数通常不是一个好主意

原因是在这两个操作期间动态调度很奇怪。对象的实际类型在构造过程中更改,而在销毁过程中又更改。当一个析构函数被执行时,对象就是那个类型,而不是从它派生的类型。动态调度始终有效,但虚函数的最终覆盖器会根据你在层次结构中的位置而改变。

也就是说,您永远不应期望在构造函数/析构函数中调用虚函数,以任何派生自正在执行的构造函数/析构函数类型的类型执行。

但是

在您的特定情况下,final 覆盖器(至少对于层次结构的这一部分)是 高于您的级别。此外,您根本没有使用动态调度PrivateBase::FunctionCall(); 调用是静态解析的,实际上等效于对任何非虚拟函数的调用。该函数是否为虚拟这一事实不影响此调用。

所以是的按照您的方式做是很好的,尽管您将被迫在代码审查中解释这一点,因为大多数人都了解规则的真言而不是其原因。 p>

关于c++ - 从析构函数调用虚函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12092933/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com