<Previous Lesson

Introduction to Programming

Next Lesson>

Lesson#29

Lesson 29

Summary


6) Friend functions
7) Declaration of Friend Functions
8) Sample Program 1
9) Sample Program 2
10) Sample Program 3
11) Friend Classes
12) Summary


Friend functions


Today, we are going to discuss a very interesting subject i.e. Friend Functions. We will
see what is the relationship of friendship with our object-based programming. Before
going into details of the subject, it is better to have a fresh look on the definition of
‘class’. ‘Class is a user defined data type’. The ‘class’ provides encapsulation facility to
the programmer. We can gather data at some place and some function that manipulates
that data. In the previous lecture, two keywords, ‘private’ and ‘public’ were introduced.
We define data members as ‘private’ that are visible only from inside the class and
hidden from the outside. However, ‘public data member functions’ is the interface of the
class available for outside world. Objects are accessed by these functions that can
manipulate the private data of the class. We cannot access the private data of the class
directly. This concept of data encapsulation and data hiding is very important concept in
software engineering. It allows us to separate the interface from the implementation of
the class i.e. we can hide how we have done the task and make visible what to do. It is
critically important for large and complex systems. Sometimes, a need may arise to
access the private data of the class from outside.
Let’s talk about the concept of friendship. What you see on the screen during the lecture
is the picture of the instructor. This is the public interface. That is all you know. What is
Page 364
inside his mind you never know. It is all ‘private’. The instructor has access to his own
mind and feelings. But you do not have access to that. Do you know any human being
who has access to your mind and feelings? What we call that human being. He is known
as friend. Normally other people don’t know about our thoughts. Only friends know
about it. Friends have access to the inner thoughts and have inner knowledge of a friend.
Can we apply this definition to objects?
The friend functions of a class have access to the private data members of class. Despite
being a good thing, there is possibility of vulnerability. We are opening our thoughts,
inside view for somebody else. Without having 100% trust, it will be risky to make our
thoughts and feelings public. We want that our private data is accessible to someone
outside, not public for everybody. Otherwise, the data encapsulation and data-hiding
concept will be violated. We keep the data members private and declare some specific
functions that are not member of the class but friend of the class. As friends, they have
access to the inside data structure of the class despite not being members.

Declaration of Friend functions


To declare a friend function, we can put it anywhere in the class. According to the
definition of the friend functions, they have access to the private data members of the
class. These can also access the private utility functions of the class. The question arises
where we should put the friend function whether in the private or public part of the class.
Be sure that friend is a very strong statement. It is too strong to be affected by public or
private. We can put it anywhere in the class. But remember that friend functions are not
member of the class. So their definition will be always outside the class. However, the
prototype of the function will be written in the class. We use the keyword ‘friend’ before
the prototype of the function.
friend return_type friend_function_name(int, char);
If we have a class, suppose ‘Date’ and want to declare a friend function of this class. In
the definition of the class, we will write the friend function’s prototype with the keyword
‘friend’. To access the private data, friend function will need the object. Therefore,
usually in the parameter list of friend function, we provide the object of that class.
Normally, the programmers work this way. As the friend function is not affected by the
private or public keyword, so we can declare it anywhere inside the class definition.
Programmers generally declare the friend functions at the top of the class definition. So,
the friend functions are declared at the start of the class definition, followed by the
private data and public data. This is a guideline. You can develop your own style. We
normally make a header file of the class definition and implementation in the other file.
The member functions are defined in the implementation file and compiled to get an
object file. We declare the friend function in the class definition that is in the header file.
Let’s go back to the definition of the friendship. I can declare you my friend and tell you
about my inner thoughts and feelings. But it does not work both ways. In other words,
friendship is granted, never taken. So, a class can declare a friend function and someone
from outside the class cannot declare itself friend of a class. This is also an important
Page 365
concept. If someone from outside the class can declare itself friend of the class, then by
definition that external function would have access to the private data member of the
class. But this will negate the concept of the encapsulation and data hiding. It does not
work this way. A function cannot declare itself friend of a class. Rather, a class has to
declare itself that a function is friend of the class or not. So the class declares a friend
function. These functions can not declare themselves friend of a class from outside. Once,
the friend functions are declared and the class is compiled, no one from outside cannot
make his function friend of your class. Outside functions can only view the interface of
the class.
Let’s summaries this concept. Friend functions are not member functions of the class.
The class itself declares the friend functions. The prototype of friend functions is written
in the definition of the class with the keyword ‘friend’. These functions have access to the
private data member of the class, which means they have access to everything in the
class. Normally we pass an object of the class to these functions in the argument list so
that it can manipulate the data of the object. Style is up to you but normally we write
friend functions at the top of the class definition.

Sample Program 1


We have a class with a single private data member of type int. We have declared a friend
function that accepts an object of that class as argument. We call that friend function
increment
. This friend function will increment the private integer data member of the
class. We will give another integer argument to that function that will be added to the
data member. The name of the private data member is, for example, topSecret. Let’s call
the class as myClass. In the interface, we write display() function that will print the value
of the topSecret. The constructor of the class will initialize the topSecret with 100. The
definition of the friend function will be outside the class. We do not write the keyword
‘friend’ with the function definition. It will be a void function, having two arguments as:
void increment(myClass *a, int i)
{
a->topSecret += i;
}
Now the increment function has added the value of i to the private data member i.e.
topSecret
of the passed object. In the main function, we declare an object of type myClass
as myClass x; On the execution of this statement, an object will be created in the
memory. A copy of its data members and functions will also be created besides calling a
constructor. The place for topSecret will be reserved in the memory while the constructor
will assign the value 100 to the variable topSecret. Now if we say x.display(); it will
display the value of the topSecret i.e.100. After this, we call the increment friend function
and pass it &x and 10 as arguments. Again we call the display function of myClass as
x.display();
Now the value of the topSecret will be 110. That means the ‘topSecret’ which
was the private data member of the class has been changed by the increment friend
function. Be sure that the increment function is not the member function of the class. It is
an ordinary function sitting outside the class but class itself has declared it as friend. So
Page 366
now the friend function has access to the private data member and has the ability to
change it. Try to write an ordinary function (not friend function) ‘increment2’ which tries
to manipulate the topSecret. See what will happen? The compiler will give an error that a
non- member function can not access the private data of the class.
Here is the complete code of the program.
/*
A sample program showing the use of friend function,
which access the private data member of the class.
*/
#include <iostream.h>
class myClass
{
friend void increment(myClass *, int);
private:
int topSecret;
public:
void display() { cout << "\n The value of the topSecret is " <<
topSecret; }
myClass();
};
// constructor of the class
myClass::myClass()
{
topSecret = 100;
}
// Friend function definition
void increment(myClass *a, int i)
{
a->topSecret += i; // Modify private data
}
// showing the use of the friend function
void main()
{
myClass x;
x.display();
increment(&x, 10);
x.display();
}
Page 367
The output of the program is:
The value of the topSecret is 100
The value of the topSecret is 110

Sample Program 2


Let’s consider some complex example. We have two classes-myClass1 and myClass2.
Both classes have one private data member of type int i.e. int topSecret; Now we want to
add the values of private data members of both the classes and display it on the screen.
topSecret
is a private data member of both the classes. One class can not see inside the
other class. myClass1 and myClass2 are both separate classes. We need a function sitting
outside the classes but can access the private data members of both the classes. Let’s call
the function as addBoth. This function will add the value of topSecret of myClass1 to
topSecret
of myClass2 and display the result on the screen. We need a function that can
look inside both classes i.e. friend of both classes. We know that classes have to declare a
function as friend.
The arguments of addBoth function will contain myClass1 and myClass2. In the
definition of the myClass1, we will write the prototype of addBoth function as:
friend void addBoth(myClass1, myClass2);
Can we write this line in the definition of the myClass1? We know that if we refer some
function as f(x) and the function f() is not defined or declared before this, the compiler
will give an error that function f() is not defined. So we at least declare the function
before main() so that compiler successfully compile the program. So there was
declaration of the function before its being called. Now same problem is in our friend
function prototype. We are referring both classes in it and our program does not know
anything about myClass2. We can tackle this problem by writing a line before the
definition of the class myClass1 as:
class myClass2;
It will declare that myClass2 is a class having its definition somewhere else. It is the same
as we declare functions before main. After writing that statement, we can refer myClass2
in our code. The definition of the class myClass1 will be as:
class myClass1
{
private:
int topSecret;
public:
void display() { cout << "\nThe value of the topSecret is " <<
topSecret; }
myClass1();
Page 368
friend void addBoth(myClass1, myClass2);
};
myClass1::myClass1()
{
topSecret = 100;
}
The definition of myClass2 is also similar to myClass1.
class myClass2
{
private:
int topSecret;
public:
void display() { cout << "\nThe value of the topSecret is " <<
topSecret; }
myClass2();
friend void addBoth(myClass1, myClass2);
};
myClass2::myClass2()
{
topSecret = 200;
}
You must have noted that we have used the topSecret data member in both the classes. Is
it legal? Yes it is. There is no problem as one topSecret is part of myClass1 and other is
part of myClass2. Will there be same problem while declaring the friend function in
myClass2,
i.e. myClass1 is not known? No. We have already defined the myClass1. We
have to declare a class only at a time when we are referring to it and it is not defined yet.
In the main program, we will take the object of myClass1 i.e. myClass1 a; The object will
be created in the memory and constructor is called to initialize the data members. The
value of topSecret will be 100. In the next line, we will take the object of myClass2 as
myClass2 b;
Now b is an object of class myClass2. The memory will be reserved for it. It
has its own data members and the value of topSecret will be 200, initialized by the
constructor. Now we will display the values of both data members, using display()
function.
Now we will call the addBoth(a, b); As this function is friend of both classes, so it has
access to both the classes and their private data members. The definition of addBoth
function will be as under:
Page 369
void addBoth(myClass1 a, myClass2 b)
{
cout << “\nThe value of topSecret in the myClass1 object is ” <<
a.topSecret;
cout << “\nThe value of topSecret in the myClass2 object is ” <<
b.topSecret;
cout << “\nThe sum of values of topSecret in myClass1 and
myClass2 is ” << a.topSecret + b.topSecret;
}
This is an interesting function. Despite not being the member of any class, it can access
the data of both the classes. This function is friend of both the classes.
Here is the complete code of the program.
/*
A sample program showing the use of friend function,
which access the private data members of two classes.
*/
#include <iostream.h>
class myClass2; // declaring the class for the friend function in myClass1
// definition of the myClass1
class myClass1
{
// private data members. Hidden
private:
int topSecret;
// interface of the class
public:
void display() { cout << "\nThe value of the topSecret is " << topSecret; }
myClass1();
// friend function
friend void addBoth(myClass1, myClass2);
};
// definition of the constructor.
myClass1::myClass1()
{
topSecret = 100;
}
// Definition of the myClass2
Page 370
class myClass2
{
// private data members. Hidden
private:
int topSecret;
// interface of the class
public:
void display() { cout << "\nThe value of the topSecret is " << topSecret; }
myClass2();
// friend function
friend void addBoth(myClass1, myClass2);
};
// definition of the constructor.
myClass2::myClass2()
{
topSecret = 200;
}
// The definition of the friend function which is adding the topSecret data member of both
the classes.
void addBoth(myClass1 a, myClass2 b)
{
cout << "\nThe value of topSecret in the myClass1 object is " <<
a.topSecret;
cout << "\nThe value of topSecret in the myClass2 object is " <<
b.topSecret;
cout << "\nThe sum of values of topSecret in myClass1 and
myClass2 is " << a.topSecret + b.topSecret;
}
// main program
void main()
{
// declaring the objects and displaying the values
myClass1 a;
myClass2 b;
a.display();
b.display();
// calling friend function and passing the objects of both the classes
addBoth(a, b);
}
Page 371
The output of the program is;
The value of the topSecret is 100
The value of the topSecret is 200
The value of topSecret in the myClass1 object is 100
The value of topSecret in the myClass2 object is 200
The sum of values of topSecret in myClass1 and myClass2 is 300
The classes have defined and declared this function addBoth to be a friend. In each class,
we have declared it as a friend function. This function cannot declare itself a friend
function for these classes from outside. So be careful about this as a class declares its
friend functions. A function out side the class cannot declare itself a friend of the class.
The friend functions are not used very often.

Sample Program 3


Now we can expand our previous example. We can define functions subBoth, mulBoth
and divBoth as friend functions of the class, in addition of addBoth function. These friend
functions can manipulate the data members of the class.
Following is the code of the example that shows the usage of friend functions.
/* The following program demonstrate the declaration and uses of friend functions of a
class
We set values in the constructors of the classes. The program prompts the user to enter a
choice of addition, subtraction, multiplication or division. And then performs the
appropriate
operation by using the friend functions.
*/
#include <iostream.h>
#include <stdlib.h>
class myClass2; // declaration of the myClass2 for the friend functions
class myClass1
{
private:
float value ;
public:
myClass1 ( )
{
value = 200 ;
}
// friend functions
friend float addBoth ( myClass1, myClass2 ) ;
Page 372
friend float subBoth ( myClass1, myClass2 ) ;
friend float mulBoth ( myClass1, myClass2 ) ;
friend float divBoth ( myClass1, myClass2 ) ;
};
class myClass2
{
private:
float value ;
public:
myClass2 ( )
{
value = 100 ;
}
// friend functions
friend float addBoth ( myClass1 , myClass2 ) ;
friend float subBoth ( myClass1 , myClass2 ) ;
friend float mulBoth ( myClass1 , myClass2 ) ;
friend float divBoth ( myClass1 , myClass2 ) ;
};
void main ( )
{
myClass1 myClass1Obj ; //create an object of class myClass1
myClass2 myClass2Obj ; //create an object of class myClass2
char choice;
cout << "Please enter one of the operator +, -, /, * " << "followed by Enter " <<
endl;
cin >> choice;
if ( choice == '+' )
{
cout << "The sum is : " << addBoth(myClass1Obj , myClass2Obj) << endl;
}
else if ( choice == '-' )
{
cout << "The difference is : " << subBoth(myClass1Obj , myClass2Obj) << endl;
}
else if ( choice == '*' )
{
cout << "The multiplication is : " << mulBoth(myClass1Obj , myClass2Obj) <<
endl;
}
else if ( choice == '/' )
Page 373
{
cout << "The division is : " << divBoth(myClass1Obj , myClass2Obj) << endl;
}
else
{
cout << "Enter a valid choice next time. The program is terminating" << endl;
}
system ( "PAUSE" ) ;
}
float addBoth ( myClass1 object1 , myClass2 object2 )
{
return ( object1.value + object2.value ) ;
}
float subBoth ( myClass1 object1 , myClass2 object2 )
{
return ( object1.value - object2.value ) ;
}
float mulBoth ( myClass1 object1 , myClass2 object2 )
{
return ( object1.value * object2.value ) ;
}
float divBoth ( myClass1 object1 , myClass2 object2 )
{
return ( object1.value / object2.value ) ;
}
Following is the output of the program.
Please enter one of the operator +, -, /, * followed by Enter
*
The multiplication is : 20000

Friend Classes


We have seen that a class can define friend functions for itself. Similarly a class can be
declared as a friend class of the other class. In that case, the function of a class gets
complete access to the data members and functions of the other class. So it is an
interesting expansion of the definition that not only the functions but also a class can be a
friend of the other class. The syntax of declaring a friend class is that within the class
definition, we write the keyword friend with the name of the class. It is going to be a
friend class. i.e. friend class-name;
We can also write the word class after the keyword friend and before the class name as
friend class class-name ;

Page 374
Now let’s take another example of a class. Suppose, we have classes ClassOne and
OtherClass
. We want to make OtherClass a friend class of the ClassOne. So we declare
OtherClass
a friend class in the definition of the ClassOne as following.
class ClassOne
{
friend OtherClass ;
private:
//here we write the data members of ClassOne
};
The line
friend OtherClass ;
can also be written as
friend class OtherClass ;
The line friend OtherCalss; explains that OtherClass is a friend of ClassOne. If
OtherClass
is the friend of ClassOne, all the functions of OtherClass will have access to
all the inside part of ClassOne.
The following code segment shows the declaration of friend class. It shows that
OtherClass
is a friend of ClassOne so it has access to the private data of ClassOne.
class ClassOne
{
friend class OtherClass;
private:
int topSecret;
};
class OtherClass
{
public:
void change( ClassOne co )
};
void OtherClass::change( ClassOne co )
{
co.topSecret++; // Can access private data of class one
}
The friend keyword provides access in one direction only. This means that while
OtherClass
is a friend of ClassOne, the reverse is not true. Here ClassOne declares that
OtherClass
is my friend. But it does not work the other way. It does not mean that
ClassOne
has access to the inside data members and methods of OtherClass. Thus, it is a
one way relationship i.e. the OtherClass can look into ClassOne, but ClassOne cannot
Page 375
look inside OtherClass. If we want a two-way relationship, OtherClass will have to
declare ClassOne as a friend class, resulting in a complete two-way relationship.
Like functions, a class cannot declare itself a friend of some other class. A class can
declare its friend classes in its declaration and cannot be a friend of other classes by
declaring itself their friend. In the above example, ClassOne declares that OtherClass is
my friend class. So otherClass can access all the data members and methods (private,
public or utility functions) of ClassOne. It does not (and cannot) declare that I
(ClassOne) am a friend class of OtherClass. So ClassOne has no access to private data
members and methods of OtherClass. It can access these only if OtherClass declares
ClassOne
as its friend. This means that by using the keyword friend, a class gives rights
of accessing its data members and methods to other classes and does not get the rights to
access other classes.
By declaring friend functions and classes, we negate the concept of data hiding and data
encapsulation and show the internal structure of the class to the friends. But the good
thing in it is that a class declares its friends while the other functions or classes cannot
look inside the class. The disadvantage of friend classes is that if we declare such a
relationship of friendship for two classes, this will become a pair of classes. To explain it
we go back to the concept of separating the interface and implementation. In case of
change in the implementation of ClassOne, the private data structure will also change.
For example, at first we have an integer variable int i; and later, we need two more
variables and we write it as int j, k, l; As the implementation of ClassOne has now
changed, the functions of OtherClass that wanted to manipulate the members of
ClassOne
will not work now. It is critically important that friend classes should be
declared very carefully. When is it necessary? This can be understood by an example
from mathematics. We have straight line in math. The equation of straight line is: y = mx
+ c. Here m is the slope of line i.e. the angle which the line makes with x-axis. And c is
the intercept at y-axis. So if we have to define a straight line, there is need of two
numbers i.e. m and c. Now if we have to define a class StraightLine, the private data of it
will be double m, c; or let’s use the names which are self explanatory like double slope,
intercept
; And then in the class, there will be the methods of the class. We can write it as
calss StraightLine
{
//some methods
private:
double slope, intercept ;
};
Now we can also have another class quadratic that also belongs to mathematics. Suppose,
we have a parabola, the equation of which is y= ax2 + bx + c. Where a, b and c, for the
time being, are real constants. To define this quadratic equation as class, we have to
define the three coefficients a, b and c. The statement will be as under:
class Quadratic
{
//some methods
Page 376
private:
double a, b, c ;
};
Now we have two classes i.e. StraightLine and Quadratic. In a mathematical problem,
when we have given a parabola (a quadratic equation) and a straight line (straight line
equation) and are asked to find the point at which the straight line intersects the parabola.
To solve it, we setup equations and solve them simultaneously and find out the result,
which may be in three forms. Firstly, there is the line that does not intersect the parabola.
The second is that it intersects the parabola at one point (i.e. it is a tangential line) and
third may be that the line intersects the parabola at two points.
When we setup these equations, we come to know that here the constants m, c(of straight
line), a, b and c of quadratic equation are being used. So from a programming perspective
if we had an object l1 of type StraighLine and an object q1 of type quadratic. And wanted
to find the intersection of l1 with q1. Now here is a situation where we need either a
friend function of both classes, so that it can manipulate the data of both classes, or need
to declare both classes as friend classes of each other and then write their methods to find
the intersection. Similarly we can have many other examples in which a class may need
to look into the other class. But it is not some thing to be done all the time. It should be
done only when necessary. Use of friend functions is normally a better idea. Using friend
classes means that both the classes are linked with each other. If the code in any one of
the class is modified i.e. its implementation is changed, we have to recompile both the
classes. Due to change in one class, the other class also needs to be changed,
necessitating the compilation of both the classes.
So we have lost the principle of separating the interface from the implementation. Now
let’s talk about the limitations of this friendship business. Firstly, there is no transitive
dependency in friend declarations. Suppose I say student A is my friend and being a
friend he knows my thoughts and ideas. Now the student A says ”student B is my friend”
i.e. student B knows thoughts and ideas of student A. Does it mean that student B is also
my friend? Does student B knows my thoughts and ideas? The answer is no. As I have
not declared student B a friend of mine, so he (student B) does not know about my
thoughts and ideas. The same applies to the friend definition for classes. The friendship is
not transitive. It is not like ‘A is a friend of B and B is a friend of C, therefore A is a
friend of C‘. It does not work. A has to specifically declare ‘B is my friend and C is my
friend’ to make B and C friends of him. There is no transitive dependency in friend
declarations.
Secondly, I can declare you to be my friend. This means I have unveiled my thoughts and
ideas to you. But I cannot get your thoughts and ideas unless you declare me a friend of
yours. So there is no association, which means A saying B is my friend does not imply in
any way that A is a friend of B. Here B is a friend of A. But B has to declare ‘A’ its
friend. Thus the friend keyword produces one-way relationship.
Page 377

Summary


The concept of classes allows us to separate implementation from interface.
A class is a user defined data type. In a class, we declare private data members and utility
functions so that they cannot be access from outside. Similarly, we declare some parts of
the class public that become the interface for the class and can be accessed from the
outside. These interface methods or public methods can manipulate the data of the class.
This is the encapsulation and data hiding.
We have the concept of friend functions. By declaring an external function as a friend
function, that function gets the complete access to the inner structure of the class
including all private data. When classes need to be interactive, these must be declared
friends of each other. Thus we have the concept of friend classes. The use of friend
function and class is a useful feature that sometimes we need to use. But we should use it
very sparingly and carefully as it basically negates the concepts of encapsulation and data
hiding.
The principles of friendship of functions and classes are that the friendship is granted, not
taken. So a class declares its friend functions and friend classes. If a class declares
another class as a friend, it is not always reciprocal. So declaration and granting of a right
is one way. The owner of the right grants it. So the class itself grants the privilege of
access to outsider functions or to other classes. It is not transitive. It does not go ‘A is a
friend of B and B is a friend of C therefore A is a friend of C’. It does not work that way.
It is restricted to a one-step relationship. If A is a friend of B, and B is a friend of C. If A
wants C to be a friend, it has to declare, “C is my friend”.

<Previous Lesson

Introduction to Programming

Next Lesson>

Home

Lesson Plan

Topics

Go to Top

Copyright © 2008-2013 zainbooks All Rights Reserved
Next Lesson
Previous Lesson
Lesson Plan
Topics
Home
Go to Top