考虑这个简单的情况:
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类的指针,该类并不是A类的子类。但运行时类型仍然是指向C实例的指针。
从Java的角度来看,这种奇怪的行为背后的确切C++规则是什么?
dynamic_cast
将正确地遍历您的层次结构。当您转换不相关的指针类型时,您会得到未定义的行为。这意味着任何事情都可能发生,从看起来工作正常到炸毁您的计算机。 - GManNickG