具有
#include <iostream>
using namespace std;
class A {
public:
virtual void foo() {
cout << "A" << endl;
}
};
class B : public A {
public:
void foo() {
cout << "B" << endl;
}
};
class C : public B {
public:
void foo() {
cout << "C" << endl;
}
};
int main() {
C c;
B* b = &c;
b->foo();
return 0;
}
输出为C
,但我预计B
。
我没有使用B::foo()
修饰符声明virtual
,所以我希望函数调用由静态类型(无多态性)决定。
为什么要调用C::foo()
?
是否可以在派生类中提供非虚函数,将虚函数隐藏在基类中?派生成员函数应具有哪些签名,以便b->foo()
调用它,而不是(b->*&A::foo)()
答案 0 :(得分:2)
成员函数的虚拟继承原理是C ++标准的直接结果:
10.3 / 2:如果虚拟成员函数vf在类Base和Derived类中声明,直接或间接从Base派生, 一个具有相同名称的成员函数vf,parameter-type-list, 与Base :: vf相关的cv-qualification和refqualifier(或不存在) 声明,然后Derived :: vf 也是虚拟的。
因此,无论继承级别如何,该函数都将在A中以某种方式从A派生的所有类中都是虚拟的。不需要放置关键字virtual
。
这种多态方法的目标是确保始终调用与对象的真实对象相对应的适当函数,而不管您使用指向基类的指针还是指向对象真实类的指针。这就是你获得“C”的原因!
在this related SO question中,我解释了一个技巧,即使用多重继承给人一种在单一级别上删除虚拟性的印象。但是,它只能用于单个级别(您应该为基础指针的类执行此操作)。
*顺便说一下,你可以写pb->B::foo();
不需要*&
。