问题
If I have three classes, A, B, C. A and B are friends (bidirectionally). Also, B and C are friends (bidirectionally). A has a pointer to B and B has a pointer to C. Why can't A access C's private data through the pointer?
Just to clarify: This is a pure theoretical C++ language question, not a design advice question.
回答1:
Friendship in C++ is not transitive:
John is a friend of mine and he can use my wireless connection any time (I trust him).
John's friend Tim though is a waster and though John is my friend I do not include Tim as a friend, and thus I don't let him use my wireless connection.
Friendship is NOT inherited
Also John's children are a bunch of hooligans so I don't trust them either they are definitely not my friends nor are my own children who I trust as far as I could throw them.
Though our children can not directly accesses the wireless they can get access to it if they go through us. So John's children can access my wireless if they access it via John (ie they are supervised and protected by John).
Also, friendship is not symmetric.
John has a goverment job so he unfortunately is not allowed to trust anyone, especially when it comes to wireless.
You are always your own best friend.
This allows things like copy constructors where you can access the private member of another object even though there is no real accesses.
So I am also automatically friends with all my clones :-) as they are just other instances of myself.
回答2:
Friendship in C++ is not transitive:
(A is friend of B) and (B is friend of C) does not mean (A is friend of C)
Also, friendship is not symmetric.
(A is friend of B) does not mean (B is friend of A)
You have to explicitly state that A is a friend of C to be able to access C's private stuff from within A. If adding a setter and getter to a class exposes information not meant to be exposed, you should consider friends if you can't find your design being faulty (using friend is valid. It's not a sign for bad design). If you can add a setter and getter without that being destructive to the interface, then you should avoid making other classes friends. Note that a nested class is always a friend of the nesting class. So a nested class can see the privates of the nesting class.
回答3:
I just found this article while waiting for replies. It answers my question pretty well: Friend scope in C++
回答4:
Because in C++ friendship is not a transitive property. Actually it should be avoided whenever possible because it introduces complexity in a system.
Imagine that B is a mediator class and A and C are components that need to be managed, do you really think it makes sense that a button should need access to the implementation of a checkbox?
By the way, I don't see where the 'hierarchy' of your title is in the case you ask.
回答5:
This is all well summed-up here:
What does it mean that "friendship isn't inherited, transitive, or reciprocal"?
-->
It means that classes derived from a friend class don't automatically become friends (do you trust the kids of your friends?), a friend of a friend doesn't automatically become a friend (do you trust the friends of your friends?), and that a class declaring another class as "friend" doesn't automatically become a friend of that class (do you trust anyone who calls you a friend?).
from
http://yosefk.com/c++fqa/friend.html#fqa-14.4
来源:https://stackoverflow.com/questions/437250/friend-scope-in-c