2

This examples shows a derived class object being passed to a function which takes reference to base class as the parameter. Member function g(int) in the derived class hides the g(float) in the base class. I understand that and my question is not related to it.

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

Output is:

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

My question is with the output "Base::g(float)". Since the object referenced by 'b' in sampleTwo() is derived object, shouldn't the dynamic binding call the g() method of the derived class (converting float to int) ?

Barry
  • 286,269
  • 29
  • 621
  • 977
irappa
  • 749
  • 4
  • 11
  • When writing a derived class's function to override a base class's virtual, it's a great idea to start using the `override` keyword (assuming a compiler with reasonable C++11 support). That way the compiler can give you an error if the function doesn't actually override as you intended. – TheUndeadFish Jul 21 '15 at 22:48
  • I am also surprised, but my initial guess would have been to see base::g(float) called twice, not derived::g(int), since the function call in both cases matches the signature of g(float), which is a different function that g(int) (these are two different functions, your code does not make any overriding) – A.S.H Jul 21 '15 at 22:51
  • You should do `using Base::g` in `Derived` to unhide `Base::g(float)`. – WorldSEnder Jul 21 '15 at 23:11

3 Answers3

3

g(int) and g(float) are two completely different methods. Derived::g(int) does not override Base::g(float). These methods are unrelated.

Since Derived does not override g(float), your expectations about b.g(3.14f) are unfounded. As expected, b.g(3.14f) should call Base::g(float).

If you override g(float) in Derived, then b.g(3.14f) will indeed call Derived::g(float).

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
1

Dynamic dispatch invokes the final overrider. Since Derived::g hides rather than overrides Base::g, the final overrider of Base::g in Derived is still Base::g.

Brian Bi
  • 111,498
  • 10
  • 176
  • 312
0

g(float) and g(int) are different function members. If you want Derived to work, you have to use g(float) in both classes.

g() can be overloaded check out function overloading: https://en.wikipedia.org/wiki/Function_overloading

Example (g(float) and g(int) in the same class and separate functions):

class Derived : public Base {
public:

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

};