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