将派生对象作为基类引用参数传递

时间:2015-07-21 22:38:08

标签: c++ dynamic-binding

此示例显示了传递给函数的派生类对象,该函数将基类作为参数引用。派生类中的成员函数g(int)隐藏基类中的g(float)。我理解这一点,而我的问题与此无关。

class Base {
public:
    virtual void g(float x) throw()
    {
        cout << "Base::g(float)\n";
    }
};

class Derived : public Base {
public:        
    virtual void g(int x) throw() // Bad: Hides Base::g(float)
    {
        cout << "Derived::g(int)\n";
    }
};


void sampleTwo(Base& b, Derived& d)
{
    b.g(3.14f);
    d.g(3.14f); // Bad: Converts 3.14 to 3 and calls Derived::g(int)
}

int main()
{
    Derived d;
    sampleTwo(d, d);
    return 0;
}

输出是:

Base::g(float)
Derived::g(int)

我的问题是输出&#34; Base :: g(float)&#34;。由于&#39; b&#39;引用的对象在sampleTwo()中是派生对象,不应该动态绑定调用派生类的g()方法(将float转换为int)?

3 个答案:

答案 0 :(得分:3)

g(int)g(float)是两种完全不同的方法。 Derived::g(int)不会覆盖Base::g(float)。这些方法无关。

由于Derived未覆盖g(float),因此您对b.g(3.14f)的期望是没有根据的。正如所料,b.g(3.14f)应致电Base::g(float)

如果您在g(float)中覆盖Derived,则b.g(3.14f)确实会致电Derived::g(float)

答案 1 :(得分:1)

动态调度会调用最终的覆盖。由于Derived::g隐藏而不是覆盖Base::gBase::gDerived的最终覆盖仍为Base::g

答案 2 :(得分:0)

g(float)g(int)是不同的功能成员。如果您希望Derived起作用,则必须在两个类中使用g(float)

g()可以重载检出函数重载: https://en.wikipedia.org/wiki/Function_overloading

示例(g(float)g(int)在同一个类和单独的函数中):

class Derived : public Base {
public:

    void g(float x) throw();
    void g(int x) throw();

};