views:

158

answers:

5

Below program contains two show() functions in parent and child classes, but first show() function takes FLOAT argument and second show() function takes INT argument.

.If I call show(10.1234) function by passing float argument, it should call class A's show(float a) function , but it calls class B's show(int b).

#include<iostream>
using namespace std;

class A{
        float a;
public:
        void show(float a)
        {
                this->a = a;
                cout<<"\n A's show() function called : "<<this->a<<endl;
        }
};

class B : public A{
        int b;
public:
        void show(int b)
        {
                this->b = b;
                cout<<"\n B's show() function called : "<<this->b<<endl;
        }
};

int main()
{
        float i=10.1234;
        B Bobject;
        Bobject.show((float) i);
        return 0;
}

Output:

B's show() function called : 10

Expected output:

A's show() function called : 10.1234

Why g++ compiler chosen wrong show() function i.e class B's show(int b) function ?

+1  A: 

There is no polymorphism involved here. You should declare your functions virtual to make them polymorphic, and make them have the same signature.

Péter Török
Some people call function overloading "compile-time polymorphism", although in C++ it usually refers to CRTP.
Nemanja Trifunovic
I am using show() function with different sugnaturtes, so Virtual key word not required. If signaturessame, then only we suppose to use Virtual key word. Correect me if I am wrong ?
siva
@Nemanja Interesting, never heard of that. Although I see the analogy, IMHO it is imprecise use of the term. Just my 2 cents :-)
Péter Török
@siva That's my point. In other words, the title of your post is incorrect.
Péter Török
+12  A: 

If you have a function in a derived class that has the same name as a function in the base class, it hides all of the functions in the base class. You either need to rename your function, or use a using declaration in your derived class:

using A::show;

or, you can explicitly call the base class function:

Bobject.A::show(i);
James McNellis
+1 - i didn't know about the using directive to unhide hidden functions. yay.
Chris Becke
@Chris: using directive is what imports a namespace. Different thing.
Potatoswatter
+1  A: 

Use a using declaration.

class B : public A{
        int b;
public:
        using A::show;
        …
};
Potatoswatter
+1  A: 

You're mixing things:
If you had 2 functions in class A with the following signatures:
void Show(int a);
void Show(float a);

Then the compiles would have chosen the "correct" function.

Shaihi
+1  A: 

When you define a name in a derived class, it hides the name from the base class.

You can achieve what you want by adding this to B's definition:

using A::show;

That will let you use both A's show() and B's show().

Kristopher Johnson