The rules are summarized as
- Friend access is one way.
- Friends of a friend have no access.
- Children of a friend have no access.
- Children of a parent with a friend will allow the friend to access them like the parent.
IE friend access of a derived class is limited to interface present on the original base class only. Virtual functions will operate as normal if they are accessible.
Example code;
#include <iostream> using namespace std; class FriendOfFriendA; class FriendA; class A{ public: A() : stuff(8) {} int get(){return stuff;} protected: virtual int vget(){return stuff;} int stuff; friend class FriendA; }; class KidA : public A { public: KidA() : A(), kidStuff(9) { stuff = 16; } protected: int kidGet(){return kidStuff;} virtual int vget(){return kidStuff;} int kidStuff; }; class FriendA{ public: int getA(A& a){return a.stuff;} int getKidA(KidA& a){return a.stuff;} //int getKidAstuff(KidA a){return a.kidStuff;} //BAD only a's stuff is a friend //int getKidAstuff(KidA a){return a.kidGet();} //BAD only a's stuff is a friend int getVirtualA(A* a){return a->vget();} friend class FriendOfFriendA; static int pubStaticGetA(A& a) { return a.stuff; } private: static int privStaticGetA(A& a) { return a.stuff; } }; class FriendOfFriendA{ public: //int getADDirect(A& a){return a.stuff;} //BAD no freind of a friend access int getAIndirect(A& a){return FriendA::pubStaticGetA(a);} int getADoubleIndirect(A& a){return FriendA::privStaticGetA(a);} }; class FriendAKid : public FriendA{ public: //int getADDirect(A& a){return a.stuff;} //BAD no child of a friend access int getADIndirect(A& a){return getA(a);} }; int main() { A a; KidA kidA; FriendA friendA; FriendAKid friendAKid; FriendOfFriendA friendOfFriendA; cout << "friendA.getA(a) : " << friendA.getA(a) << endl; cout << "friendA::pubStaticGetA(a) : " << FriendA::pubStaticGetA(a) << endl; cout << "friendA.getVirtualA(a) : " << friendA.getVirtualA(&a) << endl; cout << "friendA.getVirtualA(kidA) : " << friendA.getVirtualA(&kidA) << endl; cout << "friendA.getKidA(kidA) : " << friendA.getKidA(kidA) << endl; //cout << "friendOfFriendA.getADDirect(a) : " << friendOfFriendA.getADDirect(a) << endl; cout << "friendOfFriendA.getAIndirect(a) : " << friendOfFriendA.getAIndirect(a) << endl; cout << "friendOfFriendA.getADoubleIndirect(a) : " << friendOfFriendA.getADoubleIndirect(a) << endl; cout << "friendAKid.getADIndirect(a) : " << friendAKid.getADIndirect(a) << endl; }
This produces this result:
friendA.getA(a) : 8 friendA::pubStaticGetA(a) : 8 friendA.getVirtualA(a) : 8 friendA.getVirtualA(kidA) : 9 friendA.getKidA(kidA) : 16 friendOfFriendA.getAIndirect(a) : 8 friendOfFriendA.getADoubleIndirect(a) : 8 friendAKid.getADIndirect(a) : 8
No comments:
Post a Comment