1. What is hiding
I'm afraid that something is wrong with your little example, and I suspect that your problems lie in Hiding .
Hiding is the first:
struct Base { void foo(int) { std::cout << "Base" << std::endl; } }; struct Derived: Base { void foo(float) { std::cout << "Derived" << std::endl; } }; int main(int, char* argv[]) { Derived d; int integer = 1; float floating = 2; d.foo(floating);
The problem is called Hiding , it is a problem with name resolution at compile time. The problem is that before applying the overload rules to select the βrightβ method, the compiler must first compile the set of methods to consider. To do this, he will look at the most specialized area, and then spread out of one area at a time, until he finds the name he is looking for. Unfortunately (for efficiency reasons, I think), it stops as soon as it finds functions with a name.
So what happens here:
- Look for methods named
foo in Derived : { void Derived::foo(float) }
And stop ... therefore, trying to allow foo for the int argument, he chooses the only method he has seen so far, which may be a bit surprising.
You are right that you can surpass this with the using keyword, which brings names from a different scope so that the compiler can look at them. If I add using Base::foo; in the Derived definition, the compiler will do:
- Look for methods named
foo in Derived : { void Derived::foo(float) } + using - Add methods named
foo to Base : { void Derived::foo(float), void Base::foo(int) }
And so you get what you want.
2. How to override a method
Now that you know what Hiding is and how to get around it, I would like to take the opportunity to consider your example flaws.
You should not override such methods:
struct Base { void foo(int) const { std::cout << "Base" << std::endl; } }; struct Derived: Base { void foo(int) const { std::cout << "Derived" << std::endl; } };
The problem here is that she is just Hiding , and this can be surprising.
void fooize(const Base& b) { b.foo(); } int main(int argc, char* argv[]) { Derived d; d.foo();
If you want to override, you will need the virtual . And then you will correct your classes as follows:
struct Base { virtual ~Base() {}
And then it will work as expected.
3. Cooks book on polymorphism
- You must not override a method that is not
virtual - So polymorphism means
virtual Destructor (because it will be redefined anyway) - Inheritance introduces polymorphism, use composition if you do not want it.
Unfortunately, for C ++ there is no concept of "delegation", but we must deal with the cards that are given to us.
Final note: if a class has many methods ... perhaps it can benefit from a redesign (see std::string for an example of what not to do).