Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 558
hg_git Avatar asked Sep 17 '16 05:09

hg_git


1 Answers

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

like image 145
WhiZTiM Avatar answered Oct 06 '22 01:10

WhiZTiM