3

from C++ primer 5th edition:
have a look at these classes:

class Base {
    friend class Pal;
public:
    void pub_mem();
protected:
    int prot_mem;
private:
    int priv_mem;
};

class Sneaky : public Base {
private:
    int j;
};

class Pal {
public:
    int f1(Base b){
        return b.prot_mem;  //OK, Pal is friend class
    }

    int f2(Sneaky s){
        return s.j;  //error: Pal not friend, j is private
    }

    int f3(Sneaky s){
        return s.prot_mem; //ok Pal is friend
    }
}

Here Pal is a friend class of Base, while Sneaky inherits from Base and is used in Pal. Now the very last line where s.prot_mem is invoked, author gives the reason it works because Pal is a friend class of Base. But what i read so far, my understanding tells me that it should work anywawy, because s derives from Base and prot_mem is protected member of Base Class, which should have already access to Sneaky, can you explain why i am wrong or some more elaboration please?

Daniel Daranas
  • 22,454
  • 9
  • 63
  • 116
Jason
  • 147
  • 1
  • 1
  • 7
  • If your question is about whether the code should compile _anyway_ without friendship, you could have posted it *without* friendship in the first place. It would have been much clearer. Also, the tag friend-class does not help in any way to classify this question, because you're actually asking about the behaviour _without_ friendship. – Daniel Daranas Sep 09 '13 at 14:02

3 Answers3

2

my understanding tells me that it should work anyway, because s derives from Base and prot_mem is protected member of Base Class, which should have already access to Sneaky

No, protected variable prot_mem can only be accessed by derived class member, but not by third party class member, like class Pal, if Pal is not a friend of Base.

lulyon
  • 6,707
  • 7
  • 32
  • 49
  • oh oh now i understand, when we use an Object in another class, then anything doing s.member or s->member (if pointer) can only fetch "public" members, right?? – Jason Sep 09 '13 at 14:05
1

Without friendship, Pal only sees Sneaky or Base's public members. The fact that one member of Base is protected does not benefit Pal in any way - it only benefits Sneaky.

Daniel Daranas
  • 22,454
  • 9
  • 63
  • 116
1

The thing is that while Sneaky can access prot_mem, the code you're showing is not in Sneaky, it's in Pal. If Pal was an unrelated class, it couldn't access prot_mem, which is also protected in Sneaky. However, Pal is a friend of Base, which gives it the access necessary.

Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
  • Ok thanks but isn't when we pass Sneaky object as argument and call s.prot_mem; the access is invoked by Sneaky and not by Pal??? – Jason Sep 09 '13 at 14:02
  • @Jason Access protection checks whether the *code* performing the access has the correct rights. Where does the code which performs the read of `s.prot_mem` live? It's in class `Pal`, so it has `Pal`'s access rights. IOW, the access is invoked **by** `Pal` **on** `Sneaky`. – Angew is no longer proud of SO Sep 10 '13 at 06:39