X您在 中声明一个虚函数,并在派生类中B(B::X)覆盖。如果和的参数列表不同,并且被认为不同,则不会覆盖,并且不是虚拟的(除非您已使用 virtual 关键字声明它)。相反,隐藏.XD(D::X)B::XD::XB::XD::XD::XB::XD::XD::XB::X
#include <iostream>
using namespace std;
struct B {
virtual void X() { cout << "Class B" << endl; }
};
struct D: B {
void X(int) { cout << "Class D" << endl; }
};
int main() {
D d;
B* pb = &d;
// d.X();
pb->X();
}
你甚至不能打电话d.X(),它被隐藏了D::X(int)。不过pb->X()还好。
所以在你的情况下:
struct B {
virtual void X(B& b) { cout << "Class B" << endl; }
};
struct D: B {
void X(B& b) { cout << "Class D" << endl; }
void X(D& d) { cout << "Class D" << endl; }
};
将D::X隐藏B::X. 所以d1.X(d2)和d1.X(b2)intest()无关B::X。和b1.X(d2),b1.X(b2)中将test()调用D::X。虽然B::Xd 在 D 中是不可见的,但D::X(B&)它是虚拟的,不管你是否D::X(B&)用 virtual 关键字声明。编译器知道它是一个虚函数,所以D::X(B&)被调用。
编辑:关于 b1.X(b2) 的更多解释,B::X 是一个虚函数,并且 D::X 覆盖它,所以它肯定会通过动态绑定调用 D::X。并且重载是在编译时确定的,所以它不会调用 D::X(D&)。