hg_git hg_git - 2 months ago 6
C++ Question

using-declaration doesn't works correctly

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?

Answer

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:

class ELayer : public Employee {
private:
    using Employee::showEveryDept;

protected:
    ELayer() {}

public:
    using Employee::tellName;
};

you introduced the name showEveryDept() from a base class into your derived class for unqualified lookup. That name is introduced into a private access. Meaning, no type can directly access that name (or call that function) associated with ELayer outside the class member/static functions using unqualified name, but they can using a qualifed name as you will see shortly*.

Again, this doesn't mean objects of the base class, Employee cannot call the name outside class functions using an unqualified name, since its with a public access.

It means that:

Employee* E = new Employee;
E->showEveryDept(); // works!

And:

Designer* D = new Designer;
D->showEveryDept(); // FAILS!

And a simple cast:

Designer* D = new Designer;
static_cast<Employee*>(D)->showEveryDept(); // works!

*: And qualified name lookup:

Designer* D = new Designer;
D->Employee::showEveryDept(); // WORKS! because showEveryDept() is public in Employee

But:

Designer* D = new Designer;
D->ELayer::showEveryDept();  //FAILS! because showEveryDept() is private in ELayer