Friday 22 July 2016

F.R.I.E.N.D.S.

Preamble (can and should be ignored/ skipped):
A friend in need is a friend indeed. This my dear reader is a saying as old as time. And while I have nothing but undying hope be the recipient of anyone qualified by the said phrase, I would like to talk about a different brand of friendship. Friendship described with discipline and practiced with unwavering faith. Friendship found rarely and when so, mostly in theory. Friendship lacking luster in sentiment and ELECTRONIC in nature. Friendship between a class{} and a function(). 
C++ is a wonderful language. I say this because of it being the only language I think I know a little and not because I have tamed its power to achieve things of significance let alone greatness. It is also the first programming language that I learnt. The book I followed was C++ without fear by Brian Overland. I distinctly remember the circumstances leading to this delicious learning voyage. It was the semester break from college and I had a new laptop in my possession with a folder of ebooks on great many things. So I started reading this book and learning things thoroughly and firmly. Whatever I read, I understood, but by the time I had completed just about half of the book, the semester break was over. It's funny how the start of college meant stoppage in learning (at least retardation). Anyway, my point is that I never had the opportunity to study about classes in depth from that book and hence remained unaware of C++'s powers and beauty for the better part of a semester. But when I did eventually learn about these concepts as part of my syllabus, my understanding became a bit shallow and the learning was more of a formality.
One topic that emerged in this period was that of the Friend Functions. I just kind of knew what they were but never really understood their proper usage and role in the language.
But that stops now. For the sake of completing this blog post, I have explored this topic a bit and have attempted an introductory body of text for the said topic. Here it goes:


Scope modifiers of a class:
A class is used to describe something. And like any description, it contains attributes (of the thing being described) and its behavior (capabilities, intentions, etc). Let the thing to be described be a person- any person in general (really grab on to this analogy here, I'll be using it heavily throughout). Every person needs some form of identification by which they are to be referenced by others around him. These identification attributes are mostly public knowledge i.e. known to all, openly. For example, your name, phone number, etc. But at the same time there are certain facts and things that a person need not or prefer not to share with others (and may be just with his family members: protected attributes). These correspond to private attributes of a person. You can see how intuitively all of this maps to public and private (+ protected) members of a class in C++ (and many other OO languages). The same analogy can be extended to member functions of a class and public or private behavior of a person. Just to make sure things are absolutely crystal clear moving forward, I'd like to just reiterate what you all already know (hopefully):
1. Public members of a class can be accessed by any one through an instance of that class.
2. Private members of a class can be accessed within the body of the class itself i.e. internally by the methods of the class.
3. Protected members are like private but with one leniency that they are accessible to inheriting classes as well i.e. they get inherited by children of a class as well.

Concept of friendship:
I love the Rubik's cube, almost everyone aware of my existence (sharing or encapsulating the scope of me, the instance of the class person) knows this. Hence this is a good old public fact about me. But there are things that I don't want everyone to know. Things that I chose not to share with anyone. Anyone but a friend. And then there are things that I'd like only my family and friends to know. Finally I can choose not to share something at all. So there are all this different access control orientations that we face in our life.
Someone said to me, "Computer programming is nothing but a simulation of the human mind, experiences, challenges and goals". As such it would be a shame if there wasn't a mechanism with which we can achieve similar access control as depicted above in a computer program. But don't you dare be sour, C++ has taken care of it all.

Friends in C++:
A friend (to a class) in C++ is something (a function or even a class) that has access to the private (and protected) members of that class. 
First of all let me tell you how does this friendship comes into existence.
Assume there is a class A. Class A has many public, private and protected members. We want the function B() to have access to the private and protected members of A. One way to do this would be to have B() be the member of A itself. But that would a structure taming compromise. No, that is wrong. B() is not to be the member of A. What it can be is its friend. So how can we make B() be the friend of A? Just re-declare that function inside the class body (you must not re-define it, that'd be a syntax error) and use the keyword "friend" in this declaration. Example:

void B(....)
{
      //The body of the function (with a 6 pack of abs)
}

class A
{
      //private members
protected:
      //protected members
public:
      //public members
      friend void B(....);
};

As you can see in the above example, the re-declaration must be in the public section of the class definition.
Now comes the question of how to access private and protected members of A inside B()? The answer is how you'd access anything belonging to a class: using objects. You can create as many objects inside the function body as you want and exploit their privacy all you need but the general trend among these friend functions is the passing of an object of the class as an argument. Remember this is just a common practice and not a necessity.
Now let me quickly talk about friend classes. A class can be a friend of another class. Done. There is nothing more to talk about here. Of course I'm kidding, there is tons to learn about classes being friends with other classes. First of all let me get the syntax out of your way:

class A
{
      //Like any other normal class
};

class B
{
      //private members
protected:
      //protected members
public:
      //public members
      friend class A;
};

As you have probably guessed class A is a friend to class B. What this means is that all the member functions of class A are also friends to class B.
That's it. There is nothing more to it that I know.
Remember when I say a function can be a friend of class, then that applies to any function. A member function of another class alone can be your friend (if you don't want the whole class to be your friend).

Limitations of Friendship:
  1. 1.Friendship is not implicitly reciprocated. If class A is a friend to class B then the inverse is not true. That would need an explicit desire from the programmer.
  2. 2. A derived class does not inherit the friendship of its parents. If your parents are friends with someone, then that does not mean you should be friends with them too, does it?
  3. 3. A friend function (or class) cannot be extern. This means that friend functions need to be defined in the same file as their friend class. You cannot declare a function defined in some other file as the friend of a class. Vicinity is a necessity for friendship. 
  4. 4. A friend function must not be static.


And this my dear reader is it.


No comments:

Post a Comment