2015-07-21 133 views
2

此示例显示派生类对象被传递给引用基类作为参数的函数。派生类中的成员函数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) 

我的问题是与输出 “基础::克(浮动)”。由于sampleTwo()中由'b'引用的对象是派生对象,因此动态绑定不应该调用派生类的g()方法(将float转换为int)?

+0

在编写派生类的函数以覆盖基类的虚拟时,开始使用“override”关键字(假定编译器具有合理的C++ 11支持)是一个好主意。这样,如果函数实际上没有按照你的意图重写,编译器可能会给你一个错误。 – TheUndeadFish

+0

我也很惊讶,但我最初的猜测是看到base :: g(float)调用两次,而不是派生:: g(int),因为函数调用在两种情况下都匹配g(float)的签名,这是一个不同的函数g(int)(这是两个不同的函数,你的代码不会覆盖) –

+0

你应该在'Derived'中使用Base :: g'来取消隐藏'Base :: g(float) '。 – WorldSEnder

回答

1

动态分派调用最终的覆盖。由于Derived::g隐藏而不是覆盖Base::g,因此的最终覆盖Derived仍为Base::g

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(); 

}; 
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)

如果您在Derived中覆盖g(float),那么b.g(3.14f)确实会调用Derived::g(float)

+0

谢谢。现在明白了吧。 – irappa

相关问题