Friday, January 15, 2010

Why friends are trusted more than children

I hope it is not true in reality. But in the world of C++ programming, it is true. Friend classes may access private members of a class whereas, private members are out of scope even for child classes (or classes that inherit a base class.)

Consider the following program:
class Father
{
private:
 int annualIncome;
public:
 int noOfKeys;

 void subIncome(int n)
 {
  annualIncome -=n;
 }
 friend class Fathers_Friend;
 //friend class Son; //Flag Z: In some rare circumstances, the inheriting class can also be a friend class. 
 //In that case, public members are automatically inherited and private are accessible because they are friends.
};

class Fathers_Friend
{
private:
 Father myFriend;
 int annualTax;
public:
 int noOfShoes;
 void addToFathersIncome(int n)
 {
  myFriend.annualIncome = myFriend.annualIncome + n;
  //noOfKeys++;// Not allowed because a friend does not automatically inherit everything from another class. It has to explicitly use an object of the friend class.
 }
 void assocFriend(Father f)
 {
  myFriend = f;
 }
};

class Son : public Father
{
private:
 int noOfHairCream;
public:
 void subFromFathersIncome(int n)
 {
  //Father::annualIncome = Father::annualIncome - n; //error C2248: cannot access private member declared in class 'Father
  subIncome(20000); //Have to access inheritted function's private members through a public function.
  noOfKeys++; //Can directly access public members.
  //A Son can directly inherit a father's public property, but not his private property.
  //annualIncome = 10;//Flag Z: This is accessible if Son is also a friend of Father!
 }
 
};

void main()
{
 Father father;
 Son son;
 Fathers_Friend fathers_friend;
 fathers_friend.addToFathersIncome(10000);
 son.subFromFathersIncome(20000);
}

An object of the class Father inside the friend class Friend can be used to access a private member of the class Father. None of the private members of Father are accessible to Friend except through the object of Father class. On the other hand, Son can access all public members of Father since Son inherits from Father. However, Son cannot access private members of the Father class.

Why is this so? Why are classes inheriting another class have lesser privileges than friend classes? It is so because a class declares who all are its friends inside the class definition, whereas, any class is free to inherit from another class without requiring the parent’s consent. This means, the parent knows nothing about the children classes, but it knows about the friend classes and trusts them to not misbehave.

A special case may prevail when Son inherits Father as well as is declared as a friend of Father. This case can be seen in the above program by un-commenting the Flag Z labeled statements. In this case, the Son inherits public members of the Father class as well as the private members. Son does not need an explicit object of Father, because the inherited class always has an implicit copy of the base class.

Just as a side note, I am yet to see a good example of use of friend classes. I am not aware if there is something that cannot be done without having the friend class construct. Java does not having anything like a friend class.

No comments: