C++继承和方法重载混淆
C++ inheritance and method overloading confusion
很抱歉,这太做作了,但它与家庭作业问题有关。我明白为什么一切都会发生,除了我评论的那句话。有人可以向我解释为什么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;
内写入以获得您想要的结果。
相关文章:
- 重载方法的方式会在使用临时调用时生成编译器错误
- 使用模板参数重载C++方法:如何使其适用于模板的子类?
- 从纯虚拟类 (A) 派生的指针无法访问来自纯类 (B) 的重载方法
- 一种优雅或至少可行的方法,用于使用和接受具有重载方法和运算符的不同大小的文字数组常量
- 使用 nullptr 调用重载方法是不明确的
- 具有重载方法的可变参数数据结构
- C++11 重载方法,并转发到唯一方法
- 获取特定的模板重载方法指针
- std::result_of 应用于 const 重载方法
- 重载方法的类接受模板和基类 - 如何默认某个方法
- 推导模板类重载方法的地址会导致"error: expected primary-expression before ‘decltype’"
- C++如何使用按值传递和按引用传递的重载方法
- 具有原始方法参数派生类的 C++ 重载方法参数
- SWIG:在派生类中处理基类重载方法
- 在c++中的赋值运算符重载方法中删除旧的动态分配内存
- C++选择'wrong'默认参数的重载方法
- 重写重载方法会隐藏一些重载
- 在C++中,如何从父类变量的子类调用重载方法
- 所有重载方法的别名
- 使用 SWIG 在重载C++方法中设置类型