In the following example, I'm trying to hide using Employee::showEveryDept
from the last child class Designer
by making it private in class Elayer
-
#include <iostream>
class Employee {
private:
char name[5] = "abcd";
void allDept() { std::cout << "Woo"; }
public:
void tellName() { std::cout << name << "\n"; }
virtual void showEveryDept()
{
std::cout << "Employee can see every dept\n";
allDept();
}
};
class ELayer : public Employee {
private:
using Employee::showEveryDept;
protected:
ELayer() {}
public:
using Employee::tellName;
};
class Designer : public ELayer {
private:
char color = 'r';
public:
void showOwnDept() { std::cout << "\nDesigner can see own dept\n"; }
};
int main()
{
Employee* E = new Designer;
E->showEveryDept(); // should not work
Designer* D = dynamic_cast<Designer*>(E);
D->showOwnDept();
}
But it is still compiling and the output is -
Employee can see every dept Woo Designer can see own dept
But I've explicitly made it private, see - private: using Employee::showEveryDept;
What am I doing wrong here?
You are thinking about it the wrong way.
C++ has the concept of Name Lookup, it's a well built concept that doesn't often come to our minds, but this happens everywhere a name is used. By doing:
int main()
{
Employee* E = new Designer;
E->showEveryDept(); // should not work
Designer* D = dynamic_cast<Designer*>(E);
D->showOwnDept();
}
The line, E->showEveryDept()
does an unqualified name lookup for a member (member function in this case) belonging to the class of E
. Since it's an accessible name, the program is legal.
We, also know Designer
was derived from ELayer
, where showEveryDept()
is declared private
as you did here:
class ELayer : public Employee {
private:
using Employee::showEveryDept;
protected:
ELayer() {}
public:
using Employee::tellName;
};
But what you simply did was to explicitly introduce the name showEveryDept()
from Employee
class into Elayer
; introduced into a private
access. Meaning, we cannot directly access that name (or call that function) associated with ELayer
outside the class member/static functions.
ELayer* e = new Designer();
e->showEveryDept(); //Error, the name showEveryDept is private within ELayer
However, since showEveryDept()
has a public
access within the base class of Elayer
, Employer
; it can still be accessed using qualified name lookup
ELayer* e = new Designer();
e->Employer::showEveryDept(); //Ok, qualified name lookup, showEveryDept is public
The names from Elayer
which are accessible in Designer
will be dictated by its access specification. As you can see, the name, showEveryDept()
is private, so Designer
cannot even use such name.
For your current class hierarchy and definitions, it means that, given:
Employee* E = new Designer();
ELayer* L = new Designer();
Designer* D = new Designer();
-- For unqualified lookup:
This works
E->showEveryDept(); // works!
This fails:
L->showEveryDept(); // fails; its private in Elayer
This also fails:
D->showEveryDept(); // fails; its inaccessible in Designer
-- For qualified lookup, in this case, requesting to call such function from its base class:
This fails:
D->Elayer::showEveryDept(); // fails! its private in Elayer
This works:
D->Employee::showEveryDept(); // works! its accessible in Employee
This also works:
L->Employee::showEveryDept(); // works! its accessible in Employee
Note that: introducing the name of any member function, B::func
(for example) from a base class B
, into a derived class D
, does not override B::func
, it simply makes B::func
visible to overload resolution within the context of the derived class. See the answers to this question and this
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With