C++继承和方法重载混淆

C++ inheritance and method overloading confusion

本文关键字:重载 方法 继承 C++      更新时间:2023-10-16

很抱歉,这太做作了,但它与家庭作业问题有关。我明白为什么一切都会发生,除了我评论的那句话。有人可以向我解释为什么C++正在做它正在做的事情吗?

谢谢

#include <iostream>
using namespace std;
class X0 {};
class X1: public X0 {};
class X2: public X1 {};
class Y1
{
public:
virtual void f(int v)       { cout << "Y1(int)" << endl; }
virtual void f(const X0 *x) { cout << "Y1(X0)" << endl; }
virtual void f(const X1 *x) { cout << "Y1(X1)" << endl; }
};
class Y2: public Y1
{
public:
virtual void f(const X0 *x) { cout << "Y2(X0)" << endl; }
virtual void f(const X1 *x) { cout << "Y2(X1)" << endl; }
virtual void f(const X2 *x) { cout << "Y2(X2)" << endl; }
};
int main(int argc, char * argv[])
{
X2 x2; X2 *X2Pointer = &x2;
Y2 y2; Y1 *Y1Pointer = &y2;
cout << "What is about to happen?" << endl;
//Y1 pointer points to a Y2 object.
//The Y2 class, upon being given an X2 pointer, should print Y2(X2)
Y1Pointer->f(X2Pointer);
cout << "Why did I just print Y2(X1)" << endl;
return 0;
}

Y1公开了这些重载f()

class Y1: public Y0 {
public:
virtual void f(int v)       { cout << "Y1(int)" << endl; }
virtual void f(const X0 *x) { cout << "Y1(X0)" << endl; }
virtual void f(const X1 *x) { cout << "Y1(X1)" << endl; }
// ...
};

所有其他称为f()Y0继承的方法都是隐藏的。也就是说,当您致电时

Y1Pointer->f(X2Pointer);

编译器对f()的三个重载进行重载解析,并得出结论f(const X1*)是最佳匹配并调用此函数。事实证明,这是一个virtual函数,被Y2覆盖,因此它调用Y2::f(const X1*)

重载分辨率是根据所涉及的静态类型确定的。

Y1Pointer->f(X2Pointer)匹配Y1::f(const X1 *x),因为Y1Pointer的静态类型是Y1*的,所以Y1::f(const X1 *x)是调用X2*参数f的最佳匹配。

Y1::f(const X1 *x)是虚拟的,因此调用的实际函数由动态类型确定。Y1Pointer指向一个Y2,所以f(const X1 *x)Y2版本被调用。

Y1没有消耗X2 *的重载。函数调用Y1Pointer->f(X2Pointer)的最佳匹配项是Y1::f(X1 const *)。您的Y1Pointer指向的实际对象比Y1更多的派生对象这一事实并不重要,因为它与选择哪个重载无关。

正如其他人提到的,问题是函数隐藏。但是您可以做的是在 Y1 行using Y0::f;内写入以获得您想要的结果。