我正在阅读Bruce Eckel的《用 C++ 思考》 。在第 15 章(第 1 卷)的“构造函数内部虚函数的行为”标题下,他说
如果您在构造函数中并调用虚函数会发生什么?在一个普通的成员函数中,你可以想象会发生什么——虚拟调用在运行时被解析,因为对象不知道它是属于成员函数所在的类,还是从它派生的某个类。为了一致性,您可能认为这是在构造函数内部应该发生的事情。
在这里,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
,对吧?那么“虚拟调用在运行时解决,因为对象不知道它属于成员函数所在的类,还是从它派生的某个类”是什么意思?
他是在通过基类指针的调用来解释它吗?(我真的很怀疑)在这种情况下,他不应该写“在普通成员函数中”;据我目前的理解,从同一类的另一个成员函数内部对成员函数的任何调用都不是多态的,如果弄错了,请纠正我。