分类: C/C++
2011-03-30 21:57:10
Friend
Functions and Friend Classes
It is often useful for one class to see the private
variables of another class, even though these variables should probably not be
made part of the public interface that the class supports. For instance, if you
were writing a, you
might want to use a Node class that has private data, but it would still be
convenient for the functions that actually combine nodes together to be able to
access the data directly without having to work through the Node interface. At
times, it may not even be appropriate for an accessor function to ever give
even indirect access to the data.
Friend Classes
C++ provides the friend keyword to do just this.
Inside a class, you can indicate that other classes (or simply functions) will
have direct access to protected and private members of the class. When granting
access to a class, you must specify that the access is granted for a class
using the class keyword:
friend class aClass; |
Note that friend declarations can go in either the
public, private, or protected section of a class--it doesn't matter where they
appear. In particular, specifying a friend in the section marked protected
doesn't prevent the friend from also accessing private fields. Here is a more
concrete example of declaring a friend:
class
Node |
Now, Node does not need to provide any means of accessing
the data stored in the tree. The BinaryTree class that will use the data is the
only class that will ever need access to the data or key. (The BinaryTree class
needs to use the key to order the tree, and it will be the gateway through
which other classes can access data stored in any particular node.) Now in the
BinaryTree class, you can treat the key and data fields as though they were
public:
class
BinaryTree |
Friend Functions
Similarly, a class can grant access to its internal
variables on a more selective basis--for instance, restricting access to only a
single function. To do so, the entire function
signature must be replicated after the friend specifier, including the return
type of the function--and, of course, you'll need to give the scope of the
function if it's inside another class:
friend return_type class_name::function(args); |
For instance, in our example Node class, we would use
this syntax:
class
Node |
Now the find function of BinaryTree could access the
internals of the Node class, but no other function in BinaryTree could. (Though
we might want a few others to be able to!) Note that when friends are specified
within a class, this does not give the class itself access to the friend
function. That function is not within the scope of the class; it's only an
indication that the class will grant access to the function.
friend and Encapsulation
Some people believe that the idea of having friend
classes violates the principle of encapsulation because it means that one class
can get at the internals of another. One way to think about this, however, is
that friend is simply part of a class's overall interface that it shows the
world. Just like an elevator repairman has access to a different interface than
an elevator rider, some classes or functions require expanded access to the
internals of another class. Moreover, using friend allows a class to present a
more restrictive interface to the outside world by hiding more details than may
be needed by anything but the friends of the class. Finally, friends are
particularly common in cases of operator overloading because it is often
necessary for an overloaded operator to have access to the internals of the
classes that are arguments to the operator.