Can a friend class object access base class private members on a derived class object?

后端 未结 5 1881
佛祖请我去吃肉
佛祖请我去吃肉 2021-02-19 21:39

I\'m surprised that the code below compiles.

It seems that a class befriended to the (publicly inherited) base class can access a member of the base class provided an in

5条回答
  •  清酒与你
    2021-02-19 22:12

    Object of class D is composed of 2 separate parts :

    part containing members of B 
    part containing members of D
    

    That why the concept of object slicing works when we do:

    D objD;
    B objB = objD;
    

    Now we can access from inside object of class D, the part containing members of B via objB. Compiler remembers or can distinguish between the two parts inside class D. So compiler know what is being accessed via what.

    The statement friend class F; inside class B simply tells that member functions of class F can accesses the private, protected and public members of class B. That is, for member functions of class F all the members of class B are public.

    Actually, inside every class there are three sections w.r.t accessibility:

    public
    protected
    private 
    

    So when we declare some class B:

    class B
    {
        public:
            int a;
        protected:
            int b;
        public:
            int c;
    };
    

    then following 3 sections get created inside class B as shown above.

    Now when we declare some class F to be a friend of class B:

    class B
    {
        friend class F;
        private:
            int a;
        protected:
            int b;
        public:
            int c;            
    };
    

    then the compiler creates the sections as follows:

    class B
    {
        friend class F;
        private:
            int a;
        protected:
            int b;
        public:
            int c;
            //int a;  only for member functions of class F
            //int b;  only for member functions of class F             
    };
    

    Note that int a; and int b; are now public for member functions of class F.

    Now when class D is derived publicly from class B then the public section of class B becomes public section of class D. Similary, the protected section of class B becomes protected section of class D. Therefore, the public section part of class B can be accessed via object of class D. And since B::a; and B::b; are in public section for members functions of class F, therefore B::a and B::b can be accessed via object of class D. Also note that although after derivation int a; and int b; become members of class D, still compiler is able to distinguish them and considers them a part of class B.

    Now when class D is derived privately from class B then the public section of class B becomes private section of class D. Similary, the protected section of class B becomes protected section of class D. Therefore, now the public section part inside of class B cannot be accessed via object of class D. Recall that in class B, B::a; and B::b; are originally in public section for members functions of class F but after private derivation, the members of class B i.e B::a and B::b are now in private section of class D. Therefore, B::a and B::b cannot be accessed via object of class D. Also note that although after derivation int a; and int b; become members of class D, still compiler is able to distinguish them and considers them a part of class B. After derivation the accessibility and rules of some members of class B have changed.

    Since this question somewhat relates to effect of public, protected and private derivation, therefore for completeness please see: Why can a derived class not access a protected member of its base class through a pointer to base?

提交回复
热议问题