Home > Blockchain >  Why does inheritance break access rights
Why does inheritance break access rights

Time:10-20

I've been experimenting with uniform labyrinth generation, when I've found this problem. So, I've got a labyrinth_builder (lab_bui) class which provides the base for any builder algorithm.

class lab_bui { 
protected: 
    void say_hi() { std::cout « "hi!" « std::endl; }
};

Then I create uniform_labyrinth_builder (uni_lab_bui) class inherited from lab_bui to provide base for any uniform spanning tree (labyrinth) algorithm. Uni_lab_bui has a nested class Builder which is meant to walk within the labyrinth and sometimes break walls.

class uni_lab_bui : public lab_bui { 
protected: 
    class Builder { 
    public: 
        Builder(uni_lab_bui* obj) : enclosing{obj} {} //2 overloads... WHY?
        void say_bye() { std::cout « "bye!" « std::endl; this->enclosing->say_hi(); } //no errors, because it's a nested class
    protected:
        uni_lab_bui* enclosing; 
    }; 
}; 

Then I create an aldous_broder class which inherits from uni_lab_bui. Hence, it has a Builder nested class so i can create AB_Builder nested class which inherits from a Builder. Since Builder is nested, it has all access right's to all members of uni_lab_bui and hence, to all members lab_bui. Same logic applies to AB_Builder but inheritance, somewhy breaks everything and AB_Builder cannot access protected members of lab_bui.

class aldous_broder : public uni_lab_bui { 
public: 
    void ult() { 
        AB_Builder b(this); 
        b.speak(); 
    } 
protected: 
    size_t field{ 0ull }; 
    class AB_Builder : public uni_lab_bui::Builder { 
    public: 
        AB_Builder(aldous_broder* obj) : Builder(obj){} 
        void speak() { 
            this->enclosing->say_hi(); //error because... it makes no sense - it's a nested class that can operate with protected members of aldous_broder, therefore it must be able say hi. 
            this->say_bye(); 
        } 
    }; 
}; 

Sure, I can just make aldous_broder a friend of lab_bui and everything fixes up, but it makes no sense (why should I make my own grandchild my friend only so he can brush his teeth) Also, I could try reorder thing in a way so labyrinth is nested in Builder but it makes no sense too, since builder can exist only inside labyrinth, and he must stay inside it's boundaries. Also it won't really help, since enclosing class definitely has no access to protected members of nested. So, please help me make this work, without breaking encapsulation.

UPD: just understood the cause of the problem. Enclosed is a uni_lab_bui pointer. In any scope, (except for uni_lab_bui scope) it can't be used to access lab_bui protected members. So now, i'm looking for a work around of this problem.

CodePudding user response:

AB_Builder is a member of aldous_broder, not of uni_lab_bui, so it doesn't have access to the protected members of uni_lab_buis, just of aldous_broders.

If you upcast enclosing to aldous_broder *, you can access the protected members.

class aldous_broder : public uni_lab_bui { 
public: 
    void ult() { 
        AB_Builder b(this); 
        b.speak(); 
    } 
protected: 
    size_t field{ 0ull }; 
    class AB_Builder : public uni_lab_bui::Builder { 
    public: 
        AB_Builder(aldous_broder* obj) : Builder(obj){} 
        void speak() { 
            static_cast<aldous_broder*>(this->enclosing)->say_hi();
            this->say_bye(); 
        } 
    }; 
}; 
  • Related