gpt4 book ai didi

c++ - 在成员函数中调用虚函数

转载 作者:塔克拉玛干 更新时间:2023-11-03 08:24:17 25 4
gpt4 key购买 nike

我正在阅读 Thinking in C++布鲁斯埃克尔。在第 15 章(第 1 卷)标题为“构造函数内部虚函数的行为”中,他说

What happens if you’re inside a constructor and you call a virtual function? Inside an ordinary member function you can imagine what will happen – the virtual call is resolved at runtime because the object cannot know whether it belongs to the class the member function is in, or some class derived from it. For consistency, you might think this is what should happen inside constructors.

这里 Bruce 试图解释当您在对象的构造函数中调用虚函数时,多态性不会表现出来,即只会调用当前类的函数,而不会是该函数的其他派生类版本。这是有效的,我可以理解,因为一个类的构造函数事先不知道它是为它运行还是为其他派生对象的创建而运行。此外,如果这样做,它将在部分创建的对象上调用函数,这是灾难性的。

虽然他说普通成员函数的第一句话突然让我感到困惑,但他说虚拟调用将在运行时解析。但是等等,在一个类的任何成员函数中,当你调用另一个函数(无论是虚拟的还是非虚拟的)时,它自己的类版本只会被调用,对吧?例如

class A
{
virtual void add() { subadd(); }
virtual subadd() { std::cout << "A::subadd()\n"; }
};

class B : public A
{
void add() { subadd(); }
void subadd() { std::cout << "B::subadd()\n"; }
};

在上面的代码中,在 A::add() 中调用 subadd() 时,它会总是调用 A::subadd()B 也是如此,对吧?那么他所说的“虚拟调用在运行时解析,因为对象不知道它是属于成员函数所在的类,还是属于从它派生的某个类”是什么意思?

他是在解释通过基类指针的调用吗? (我真的怀疑是这样)在这种情况下,他不应该写“在普通成员函数中”;到目前为止,根据我的理解,从同一类的另一个成员函数内部调用一个成员函数都不是多态的,如果有误请指正。

最佳答案

你错了——进一步的派生类可以覆盖一些虚函数,这意味着静态调用是错误的。因此,扩展您的示例:

class C : public B
{
public:
// Not overriding B::add.
void subadd() { std::cout << "C::subadd\n"; }
};

A *a = new C;
a->add();

这会动态调用 B::add,而 B::add 又会动态调用 C::subadd。对 B::subadd 的静态调用是错误的,因为动态类型是 C 并且 C 覆盖了该函数。

在您的示例中,将 A::add 复制为 B::add 是不必要的 - 两者都将以多态方式调用 subadd对象的动态类型。

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

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