Friend Functions & Classes
The friend keyword grants a specific non-member function, or an entire other class, access to a class's private and protected members. It is a deliberate, narrow exception to encapsulation — normally only a class's own member functions can see its private data, but a friend declaration explicitly opens the door to one named outsider.
Declaring a friend function
A friend declaration goes inside the class body, prefixed with friend. It doesn't matter which access section (public, private, protected) it's placed in — friendship isn't affected by access specifiers, since the function isn't a member at all.
Granting a free function access to private members
class Box {
private:
double volume;
public:
Box(double v) : volume(v) {}
// Declares that this specific free function may access Box's private members.
friend void printVolume(const Box& b);
};
// Not a member function — but thanks to 'friend', it can reach 'volume'.
void printVolume(const Box& b) {
std::cout << "Volume: " << b.volume << "\n";
}
int main() {
Box b(27.0);
printVolume(b); // Volume: 27
}The common real-world case: operator<< / operator>>
As seen on the Operator Overloading page, operator<< and operator>> for a custom type must be free functions, because the left operand is a stream (std::ostream / std::istream), not your class. If the data they need to print or read is private, friend is exactly the tool that lets them reach it without making that data public.
friend enabling operator<< to reach private data
class Point {
private:
int x, y;
public:
Point(int x, int y) : x(x), y(y) {}
friend std::ostream& operator<<(std::ostream& out, const Point& p);
};
std::ostream& operator<<(std::ostream& out, const Point& p) {
out << "(" << p.x << ", " << p.y << ")"; // reaches private x, y via friendship
return out;
}Friend classes
An entire class can be declared a friend, giving every member function of that class access to the private/protected members of the class granting friendship.
One class granting another full access
class Engine {
private:
int horsepower = 400;
friend class Car; // Car's member functions can access Engine's private members
};
class Car {
public:
void printEngineStats(const Engine& e) {
std::cout << "Horsepower: " << e.horsepower << "\n"; // allowed via friendship
}
};Friendship is not mutual or inherited
friendmust be granted explicitly by the class being accessed — it is not automatic or symmetric.EnginedeclaringCara friend does not makeEnginea friend ofCar.Friendship is not inherited: if
Enginegrants friendship toCar, a class derived fromCardoes not automatically inherit that friendship.
What's next
Static Members covers data and functions that belong to the class itself rather than to any one object — the last stop in this OOP section.