A friend is an entity to which a class grants access authority.
Friends can be functions, other classes, or individual member functions of other classes. Friend classes are used when two or more classes are designed to work together and need access to each other's implementation in ways that the rest of the world shouldn't be allowed to have. In other words, they help keep private things private. For instance, it may be desirable for class DatabaseCursor
to have more privilege to the internals of class Database
than main()
has.
In the early days of OO, people had all sorts of strange ideas. Some people thought that the class was the fundamental unit that had to be encapsulated and concluded that friendship was evil. Experience has shown that some abstractions require more than one class, and that the abstraction needs the encapsulation barriers more than the component classes. As long as they are used properly, friends enhance the encapsulation of abstractions.
Friend classes normally imply that one abstraction (a database with multiple cursors, for example) is implemented using several distinct classes (Database
and DatabaseCursor
). Using several classes to implement one abstraction is especially useful when the various classes have different lifetimes or different cardinalities. For example, it is likely that there are an arbitrary number of DatabaseCursor
objects for any given Database
object.
It would be a bad idea to force class Database
and class DatabaseCursor
into one class by moving the member functions of DatabaseCursor
into class Database
(so we would now have Database::getCurrentRecord()
). This would impose a one-cursor-per-database policy and would cause Database
to manage both the data and a current position within that data.
The UML diagram for this friendship relationship follows.
A secret handshake or other technique to exchange information with a confidant in such a way that normal people are unable to access the same secrets. Friend classes prevent users (the normal people) from seeing the information being exchanged through the secret codes that connect the various objects (confidants).
The overall effect is to keep private things private.
The alternative to granting special access privileges between the classes would be for the classes to declare public:
member functions that allow anyone to manipulate the class's private:
members. For instance, in the DatabaseCursor
example, class Database
would need to provide public:
member functions to manipulate its cache, B-tree, file system, and so on. Although the implementation bits would be encapsulated, the implementation technique would be exposed. Subsequent changes to the implementation technique would break users' code.
In the traditional software realm, friendship is called tight cohesion, and is, within limits, considered good.
Friend classes are useful when a class wants to hide features from users that are needed only by another, tightly coupled class. Compared to making a member public:
, it is sometimes better to make the member private:
, which eliminates potential misuse by unknown users, and grant friendship status to the tightly cohesive class, thereby keeping implementation details hidden from the rest of the world.
Friend classes also arise when a member function on a class needs to maintain state between calls and when multiple copies of this state must exist. Under these circumstances, the member function becomes a friend class, and the multiple copies of the state become multiple objects of the friend class.
Not necessarily.
If the encapsulation barrier is narrowly defined as the suite of member functions on a class, then friends violate the encapsulation barrier. However, this is a naive view of encapsulation, and applying it consistently actually degrades the overall encapsulation of a system. For example, if another entity needs to be part of the same abstraction, this naive approach suggests that the first class should expose its implementation technique via an unnecessarily large suite of get/set member functions.
The enlightened view is that the encapsulation barrier encapsulates an abstraction, not just a class. For example, the earlier example of a database with multiple cursors illustrates an abstraction that is too rich to be implemented by a single class. In cases like this, friend classes are a valuable way of hiding the (possibly complex) interrelationships between the various pieces of the abstraction.
Friends don't violate the encapsulation barrier; they are part of the encapsulation barrier.
A friend function is a nonmember function that has been granted access to a class's non-public:
members. This improves an interface without breaking encapsulation.
For example, the syntax most objects use for printing is cout << x
, where x
is the object being printed and cout
is the output stream (ostream
) on which the object is being printed. This printing service is provided by operator<<
, which needs to be a friend function of the class of x
rather than a member function of the class of x
, because the ostream
needs to be on the left side of the <<
operator and the object being printed on the right side. In general, binary operators can be member functions only if the member function is attached to the left hand argument of the operator.
Whenever it improves readability of user code.
Generally, member functions are used rather than friend functions. However if a friend function would make the code that uses the class more readable, a friend function should be used.
It is important that the decision be based not on the readability of the code within the class but rather on the readability of the code that uses the class. There isn't that much difference between the internal implementation details within a friend function and those within a member function. But even more important is the economics of the situation. It's more important to focus on the many users of the class than it is to worry about the class itself.
The point of friend functions is that they allow the syntax for the user code to be intuitive while still maintaining the class's encapsulation barrier. This can lead to easier-to-use classes, which reduces education costs and improves the quality of the user code—intuitive interfaces are abused less often.
Friend functions should be part of the class's public:
interface, and their code should be owned by the class's owner.
Guideline 1: Friend functions should make the user's code easier to understand. Look at some sample syntax of how a user would use the class with the friend function, and compare it with the moral equivalent of the sample syntax if the friend function were changed into a member function. The friend function version should be used if and only if it results in more intuitive user code (see FAQ 19.06).
Guideline 2: Friend functions should be used only for operations that are part of the public:
interface of a class. They should not be used every time someone wants to do something tricky with the class. If a user has a function that needs to access the innards of your class (for example, because the class's current public:
interface isn't powerful enough), fix the problem (the interface) rather than patching the symptoms. Don't grant friendship to everyone.
Guideline 3: A friend function or class should be under the political and technical authority of the same team that owns the class itself. Granting friendship status to a function or class under the political authority of a team other than the one implementing the class results in a scheduling headache—changes that involve coordinating multiple participants who may not always be in a position to handle the requested modifications in a timely manner is a nightmare.
A friend of a friend isn't (necessarily) a friend.
Friendship is personal; it is explicitly granted to a particular, named individual. All friends of a class are declared explicitly in the body of the class. This clearly identifies the entities that need to be updated when the private:
part of a class is changed.
In the following code, operator<<
is a friend of BinaryTree
, which is a friend of BinaryTreeNode
, but this does not make operator<<
a friend of BinaryTreeNode
.
If operator<<
needs to access BinaryTreeNode::left_
or BinaryTreeNode::right_
, it must be made a friend of BinaryTreeNode
as well:
Note that the compiler doesn't care where a friend
declaration appears within a class, so the placement is normally done to make the code easily readable by other programmers (see FAQ 19.12). In the example, normal users might be somewhat confused by the friendship relationship between BinaryTreeNode
and operator<<
, so it has been moved out of the public:
section (the public:
section is where normal users look to find out how to use a class).
Just because someone trusts you does not automatically mean they will trust your children.
Suppose class Fred
grants friendship privileges to another class Base
and class Derived
is derived from class Base
. Derived
does not automatically have friendship privileges to access the innards of Fred
just because its base class is a friend of Fred
. This rule improves encapsulation. Without this rule, anyone could automatically gain friendship (and access to internals) by deriving from a known friend.
In the following example, an EggCarton
is not supposed to have more than a dozen eggs (numEggs_ <= 12
). Class EggCartonFiller
is trusted not to violate the semantics of an EggCarton
, so EggCarton
makes EggCartonFiller
a friend. This friendship allows EggCartonFiller::addAnEgg()
to access EggCarton::numEggs_
.
If friendship were inherited, anyone could create a class derived from EggCartonFiller
and possibly violate the semantics of an EggCarton
.
Friend functions don't bind dynamically. However there is a simple one-line idiom that enables the functionality of a virtual function (that is, dynamic binding) with the syntax of a friend function. This idiom is called the virtual friend function idiom.
The virtual friend function idiom provides the effect of friend functions that bind dynamically; it is used when the syntax of a friend function is desired but the operation must be dynamically bound.
Simply put, use a friend function that calls a protected:
virtual member function. For example, suppose class Shape
is an abstract base class (ABC), and a Shape
is printed via cout << aShape
, where aShape
is a Shape&
, which refers to an object of a derived class, such as Circle
. To use the virtual friend function idiom, operator<<
would be a friend of Shape
and would call a protected:
pure virtual member function such as print(ostream&) const
.
Because print()
is virtual, the right implementation will always be invoked. Because print()
is pure virtual, concrete derived classes are required to provide a definition—Shape
doesn't have enough knowledge about itself to print itself.
Because print()
is protected:
, users must use the official syntax provided by operator<<
(this avoids cluttering the interface with two ways of doing the same thing).
The output is
Circle of radius 42
Note that there is only one operator<<
for the entire Shape
hierarchy. Derived classes provide a definition for print(ostream&) const
, but they do not declare or define operator<<
.
The three P's of friendship: position, promotion, or perception.
Position:Use a friend function when the object being operated on can't appear as the leftmost argument. For example, the syntax to print an object n
is usually cout << n
, where cout
can be replaced by any ostream
. Notice that n
is not the leftmost argument and therefore operator<<
cannot be a member of n
's class. If operator<<
needs access to n
's internal state, it must be a friend of n
's class.
Promotion: Use a friend function to allow promotion of the leftmost argument. For example, the Fraction
class might want to support 5*n
, where n
is a Fraction
object. This may require promoting the leftmost argument from an int
to a Fraction
, where this is implemented by passing a single int
parameter to Fraction
's constructor—Fraction(5)
. The operator*
needs to be a friend because C++ never automatically promotes the this
object in a member function invocation.
Perception: Use a friend function when it leads to a user syntax that is more intuitive. For example, two possible syntaxes for computing the square of a fraction n
are n.square()
and square(n)
(for example, 1/2
squared is 1/4
). If the operation is constructive (if n
is unchanged), square(n)
may be preferred because n.square()
might be incorrectly perceived as squaring n
itself.
Of the three P's for choosing between friend functions and member functions, perception is the most subjective. In many cases involving perception, a static member function such as Fraction::square(n)
is better than a friend function.
private:
, protected:
, or public:
section of a class?For documentation purposes, they should be declared in the public:
section of a class. The compiler ignores the access level (private:
, protected:
, or public:
) where friend functions are declared. However, for documentation purposes, they should normally be declared in the public:
part of the class since friend functions are inherently public:
(most friend functions are non-member functions and are therefore conceptually declared outside the class).
For an exception to this guideline, see FAQ 19.08.
A private class is a class created only for implementation purposes and is hidden from normal users. Typically, all its constructors (and often all its other members as well) are private:
and it declares another class as its friend
. Because the private class lacks public:
constructors or member functions, only the designated friend
s and other instances of the private class can create or use instances of the private class.
For example, the Node
class associated with a linked list class might be so specialized that no other class would benefit from reusing it. In this case the Node
class can be a private class and can declare the linked list class as a friend
. In the following code, class Node
is nested inside class List
. Although not strictly part of the private class concept, this technique has the further benefit of reducing the number of names in the outer namespace (nesting Node
inside List
removes the name Node
from the namespace that List
is in).
Objects of a class are normally printed via a friend function called operator<<
. Here is an example of such a friend function.
The function operator<<
is a friend rather than a member, so the Fred
parameter appears on the right side of the <<
.
Objects of a class normally receive stream input via a friend function called operator>>
. Here is an example of such a friend function.
The Fred
argument of operator>>
is passed by reference (as opposed to const
reference). This allows operator>>
to change the caller's Fred
, which is, of course, the whole point of stream input.