quick inheritance question

Hi. I'm currently reading some stuff about how names can be hidden in public inheritance. Could someone explain to me how the overloaded function becomes hidden in the following example?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Base
{
private:
int x;
public:
virtual void mf1() = 0;
virtual void mf1(int);
}

class Derived : public Base
{
public:
virtual void mf1();
}

The book states that a call like this:
1
2
int x = 5;
mf1(x);

Would be invalid because the Derived mf1() somehow overshadows both instances of mf1 in the base. I can understand how it would overshadow the pure virtual function with no arguments, but how does it overshadow the overloaded mf1 with the int argument?
Shouldn't this public inheritance basically add the base functions to the public section of the derived, similar to this?
1
2
3
4
5
6
7
class Derived
{
public:
virtual void mf1();   ///non-inherited version
virtual void mf1() = 0;  //inherited pure virtual, not that it matters
virtual void mf1(int);  //inherited, overloaded signature
}

How does the mf1() overshadow the mf1(int)?

Supposedly, a "using Base::mf1;" directive will resolve this, but I want to know why its shadowed in the first place, being a publicly inherited, overloaded function.

Thanks.
This is to do with names not the functions themselves.
names in C++ are the identifiers given to variables, classes, functions, etc..

names in c++ are scoped.

you can have several overloaded functions in a scope with the same name - but as far as names is concerned the name is only used once.
This is the whole concept between scopes and names and name hiding.

Remember back to basic exercises when you learn about scopes - you probably saw/did something like this.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//some_file.cpp

int x;  //name x at global scope

int main()
{
     int x;  // name x used again but this time in  function main() scope

      x = 3; //uses x  from main() scope

     {   //introduce an inner sope
         
          int x; //use the name x again
          x = 6; //uses the x from this scope
          ::x =9; //uses x from the global scope
     }

}


I'm sure you understod that.

So coming back to your original problem;
You have the Derived class scope (Derived::), surrounded by the Base class scope (Base::)
surrounded by the Global scope (::).
So the fact that you have re-introduced the name mf1 into the Derived class scope
hides the same name from the Base class scope.

So in Derived class you only have one function called mf1.
Note that inheritance is still happening - just that names are hidden.

As you have noticed - you can use Base:: scope resolution to use the hidden functions.
Last edited on
This is actually a very good question.

guestgulkan's explanation is excellent!

I would also like to add that part of the confusion seems to be that C++ doesn't consider the signature (unlike some languages like Smalltalk) for the purposes of resolving its virtual tables.

If it did, it would have behaved the way you expected. There is no reason why it shouldn't, except that C++ language specifications deemed it so. It's too bad because IMHO, there's not much use to variable/symbol shadowing - it usually causes more problems than it's worth.

Just to clarify, IMHO, namespaces and encapsulation are good, but shadowing is bad.
Last edited on
Ah I see... Even if overloaded, the name is only considered once per scope. Thank you. :)
Topic archived. No new replies allowed.