Lesson content
Read, practise, then check your understanding
A friend declaration grants a named non-member function or class access to private and protected members. Friendship is explicit, neither inherited nor transitive, and not automatically reciprocal.
#include <ostream>
class Point {
int x_{};
int y_{};
public:
Point(int x, int y) : x_{x}, y_{y} {}
friend std::ostream& operator<<(std::ostream&, const Point&);
};
std::ostream& operator<<(std::ostream& out, const Point& point) {
return out << '(' << point.x_ << ", " << point.y_ << ')';
}
The stream must be the left operand, so operator<< cannot naturally be a Point member. Friendship lets the symmetric non-member access representation without exposing public getters solely for formatting.
Use it deliberately
A friend class can help two tightly coupled implementation types cooperate, such as a container and its iterator. Broad friendship increases coupling and enlarges the code that can violate invariants. Prefer a public operation when it represents a genuine client capability, a member when the operation belongs to the object, and a narrowly declared friend only when privileged collaboration improves the abstraction.
A friend defined inside a non-local class is implicitly inline and is commonly found through argument-dependent lookup. Friendship does not create membership: a friend function has no this pointer and must receive objects explicitly.
Knowledge check
Answer every question correctly to complete this chapter.
0 of 10 checks passed
Your progress is saved on this device.