我知道当使用指向派生类对象的基类指针调用虚函数时,编译器会使用动态绑定来调用派生版本。但是当使用指向基类对象的基类指针调用虚函数时,编译器是使用动态绑定还是静态绑定来调用虚函数呢?
例如:
class Base
{
public:
virtual void show()
{
cout << "base class";
}
}
int main()
{
Base *pb; //Base class pointer
Base b; //Base class object
pb = &b;
pb->show(); //Is static binding or dynamic binding?
}
因为我的英语很差,所以我想让我的问题尽可能简单,但我会在下面更详细地描述我的问题:
其实问题源于我在总结如何触发动态绑定。首先我总结一下触发条件是:
- 该函数必须是一个虚函数。
- 必须使用指针或引用来调用函数。
这两个触发条件导致了我问的问题:“当基类指针指向基类对象时,编译器是否会使用动态绑定?”
我有谷歌搜索答案,我找到了一个片段(演示在这里):
struct A {
virtual void f() { cout << "Class A" << endl; }
};
struct B: A {
//Note that it not overrides A::f.
void f(int) { cout << "Class B" << endl; }
};
struct C: B {
void f() { cout << "Class C" << endl; }
};
int main() {
B b; C c;
A* pa1 = &b;
A* pa2 = &c;
// b.f();
pa1->f();
pa2->f();
}
以下是上述示例的输出:
"Class A"
"Class C"
根据pa1->f()
遗嘱输出Class A
,我总结了第三个触发条件:
3.基类中的函数必须在派生类中被覆盖。
现在根据三个触发条件,当使用指向基类对象的基类指针调用虚函数时,编译器会使用静态绑定来调用虚函数,因为虚函数没有被覆盖。
但是当使用指向派生类对象的派生类指针调用虚函数时,会使用动态绑定,因为虚函数被覆盖了。
这让我很困惑。