考虑这个简单的情况:
A.h
class A {
public:
virtual void a() = 0;
};
B.h
#include <iostream>
class B {
public:
virtual void b() {std::cout << "b()." << std::endl;};
};
C.h
#include "A.h"
#include "B.h"
class C : public B, public A {
public:
void a() {std::cout << "a() in C." << std::endl;};
};
int main() {
B* b = new C();
((A*) b)->a(); // Output: b().
A* a = new C();
a->a(); // Output:: a() in C.
return 0;
}
换句话说:
- A 是一个纯虚类。
- B 是一个没有超类和一个非纯虚函数的类。
- C 是 A 和 B 的子类,并覆盖 A 的纯虚函数。
令我惊讶的是第一个输出,即
((A*) b)->a(); // Output: b().
虽然我在代码中调用了 a(),但调用了 b()。我的猜测是,这与变量 b 是指向 B 类的指针有关,而 B 类不是 A 类的子类。但运行时类型仍然是指向 C 实例的指针。
从 Java 的角度来看,解释这个奇怪行为的确切 C++ 规则是什么?