I have been reading through the C++ FAQ and was curious about the friend declaration. I personally have never used it, however I am interested in exploring the language.
This may not be an actual use case situation but may help to illustrate the use of friend between classes.
The ClubHouse
class ClubHouse {
public:
friend class VIPMember; // VIP Members Have Full Access To Class
private:
unsigned nonMembers_;
unsigned paidMembers_;
unsigned vipMembers;
std::vector members_;
public:
ClubHouse() : nonMembers_(0), paidMembers_(0), vipMembers(0) {}
addMember( const Member& member ) { // ...code }
void updateMembership( unsigned memberID, Member::MembershipType type ) { // ...code }
Amenity getAmenity( unsigned memberID ) { // ...code }
protected:
void joinVIPEvent( unsigned memberID ) { // ...code }
}; // ClubHouse
The Members Class's
class Member {
public:
enum MemberShipType {
NON_MEMBER_PAID_EVENT, // Single Event Paid (At Door)
PAID_MEMBERSHIP, // Monthly - Yearly Subscription
VIP_MEMBERSHIP, // Highest Possible Membership
}; // MemberShipType
protected:
MemberShipType type_;
unsigned id_;
Amenity amenity_;
public:
Member( unsigned id, MemberShipType type ) : id_(id), type_(type) {}
virtual ~Member(){}
unsigned getId() const { return id_; }
MemberShipType getType() const { return type_; }
virtual void getAmenityFromClubHouse() = 0
};
class NonMember : public Member {
public:
explicit NonMember( unsigned id ) : Member( id, MemberShipType::NON_MEMBER_PAID_EVENT ) {}
void getAmenityFromClubHouse() override {
Amenity = ClubHouse::getAmenity( this->id_ );
}
};
class PaidMember : public Member {
public:
explicit PaidMember( unsigned id ) : Member( id, MemberShipType::PAID_MEMBERSHIP ) {}
void getAmenityFromClubHouse() override {
Amenity = ClubHouse::getAmenity( this->id_ );
}
};
class VIPMember : public Member {
public:
friend class ClubHouse;
public:
explicit VIPMember( unsigned id ) : Member( id, MemberShipType::VIP_MEMBERSHIP ) {}
void getAmenityFromClubHouse() override {
Amenity = ClubHouse::getAmenity( this->id_ );
}
void attendVIPEvent() {
ClubHouse::joinVIPEvent( this->id );
}
};
Amenities
class Amenity{};
If you look at the relationship of these classes here; the ClubHouse holds a variety of different types of memberships and membership access. The Members are all derived from a super or base class since they all share an ID and an enumerated type that are common and outside classes can access their IDs and Types through access functions that are found in the base class.
However through this kind of hierarchy of the Members and its Derived classes and their relationship with the ClubHouse class the only one of the derived class's that has "special privileges" is the VIPMember class. The base class and the other 2 derived classes can not access the ClubHouse's joinVIPEvent() method, yet the VIP Member class has that privilege as if it has complete access to that event.
So with the VIPMember and the ClubHouse it is a two way street of access where the other Member Classes are limited.