Friends in C++

General

Making a class or function a friend of a class gives that class of function access to the private and protected members of the first class.

Friend classes are useful when you have an entity that logically divides into several components, those components need to access each others’ members, and they don’t make sense in isolation, i.e., they’re not reusable outside the entity. So friendship allows you to define a software component as a tightly-knit group of classes rather than a single class. Without friendship and the separation of concerns this allows, classes can become monolithic, having too many member variables and methods, and too many responsibilities.

Friend functions are useful when you have a function that takes one or more instances of the class and needs access to their members, but the operation does not make sense as a method of an object, because the object(s) passed to the function cannot be seen as being the primary actors in the operation. For example, a function might take 2 instances of a class and neither of them is primary in the operation, like 2 back account objects in a transfer.

Encapsulation

It is sometimes said that friendship violates encapsulation, but this is not the case.
Friendship enhances encapsulation in the sense that it allows access to internal state without making members public.

Friendship has much less effect on encapsulation than protected member variables. A protected member variable means that the class’s internal state can be accessed by an unknown and potentially infinite number of other classes (all of the class’s subclasses). A friend declaration means that the class’s internal state can be accessed by one other named class.
If I change the protected parts of a class, I break an unknown and potentially infinite number of other classes. If I change a private part of a class that has friends, I know exactly how many classes I might break and where to look for them.
Here, the direction of friendship is important because you can trace dependencies easily by going from a class to its friends.
Inheritance is the other way round, with subclasses declaring their parent class, so you can’t easily (or often at all) trace dependencies by going from a class to its subclasses.