|
|||||
CS201
Introduction to Programming
Lecture
Handout
Introduction
to Programming
Lecture
No. 29
Reading
Material
Deitel
& Deitel - C++ How to
Program
Chapter.
7
7.4
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
363
CS201
Introduction to Programming
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
364
CS201
Introduction to Programming
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
365
CS201
Introduction to Programming
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
366
CS201
Introduction to Programming
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
367
CS201
Introduction to Programming
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
368
CS201
Introduction to Programming
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
369
CS201
Introduction to Programming
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
370
CS201
Introduction to Programming
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
371
CS201
Introduction to Programming
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
372
CS201
Introduction to Programming
{
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
373
CS201
Introduction to Programming
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
374
CS201
Introduction to Programming
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
375
CS201
Introduction to Programming
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
376
CS201
Introduction to Programming
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".
Page
377
Table of Contents:
|
|||||