Friend class
A friend class in C++ can access the private and protected members of the class in which it is declared as a friend. A significant use of a friend class is for a part of a data structure, represented by a class, to provide access to the main class representing that data structure. The friend class mechanism allows to extend the storage and access to the parts, while retaining proper encapsulation as seen by the users of the data structure.
Similar to a friend class, a friend function is a function that is given access to the private and protected members of the class in which it is declared as a friend.
Since C++26, C++ supports "variadic friends".
Example
The following example demonstrates the use of a friend-class for a graph data structure, where the graph is represented by the main class Graph, and the graph's vertices are represented by the class Vertex.import std;
template
using SharedPtr = std::shared_ptr
using String = std::string;
template
using UniquePtr = std::unique_ptr
template
using HashSet = std::unordered_set
class Vertex ;
class Graph ;
Using variadic friends:
import std;
template
class ClassWithFriends ;
class A ;
class B ;
int main
Encapsulation
A proper use of friend classes increases encapsulation, because it allows to extend the private access of a data-structure to its partswhich the data-structure ownswithout allowing private access to any other external class. This way the data-structure stays protected against accidental attempts at breaking the invariants of the data-structure from outside.It is important to notice that a class cannot give itself access to another class's private part; that would break encapsulation. Rather, a class gives access to its own private parts to another classby declaring that class as a friend. In the graph example, Graph cannot declare itself a friend of Vertex. Rather, Vertex declares Graph a friend, and so provides Graph an access to its private fields.
The fact that a class chooses its own friends means that friendship is not symmetric in general. In the graph example, Vertex cannot access private fields of Graph, although Graph can access private fields of Vertex.
Alternatives
A similar, but not equivalent, language feature is given by C#'sinternal access modifier keyword, which allows classes inside the same assembly to access the private parts of other classes. This corresponds to marking each class a friend of another in the same assembly; friend classes are more fine-grained.Programming languages which lack support for friend classes, or a similar language feature, will have to implement workarounds to achieve a safe part-based interface to a data-structure. Examples of such workarounds are:
- Make the parts' fields public. This solution decreases encapsulation by making it possible to violate invariants of the data-structure from outside.
- Move all mutable structural data away from the part to the data-structure, and introduce indirection back from each part to its data-structure. This solution changes the organization of the data structure, and increases memory consumption in cases where there would otherwise be no need for this information.
Properties
- Friendships are not symmetric – if class
Ais a friend of classB, classBis not automatically a friend of classA. - Friendships are not transitive – if class
Ais a friend of classB, and classBis a friend of classC, classAis not automatically a friend of classC. - Friendships are not inherited – if class
Baseis a friend of classX, subclassDerivedis not automatically a friend of classX; and if classXis a friend of classBase, classXis not automatically a friend of subclassDerived. However, if classYis a friend of subclassDerived, classYwill also have access to protected portions of classBase, just as subclassDeriveddoes.