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

时间:2012-11-11 14:54:39

标签: c++ inheritance overloading

对不起,这是如此做作,但它与家庭作业问题有关。我理解为什么一切都会发生,除了我评论的那一行。有人可以向我解释为什么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;
}

4 个答案:

答案 0 :(得分:3)

班级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*)

答案 1 :(得分:1)

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

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

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

答案 2 :(得分:1)

班级Y1没有超载消耗X2 *。函数调用Y1Pointer->f(X2Pointer)的最佳匹配是Y1::f(X1 const *)Y1Pointer点的实际对象比Y1更多的实际对象无关紧要,因为它与选择的重载无关。

答案 3 :(得分:0)

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