leg*_*s2k 1 c++ polymorphism virtual-functions member-functions
我正在读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"; }
};
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,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();
Run Code Online (Sandbox Code Playgroud)
这动态调用B::add,然后动态调用C::subadd.静态调用B::subadd将是错误的,因为动态类型是C并C覆盖函数.
在您的示例中,重复的A::addas B::add是不必要的 - 无论subadd对象的动态类型如何,它们都将以多态方式调用.