CppFriend Functions & Classes

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

CPP
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

CPP
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

CPP
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
  • friend must be granted explicitly by the class being accessed — it is not automatic or symmetric. Engine declaring Car a friend does not make Engine a friend of Car.

  • Friendship is not inherited: if Engine grants friendship to Car, a class derived from Car does not automatically inherit that friendship.

Use friend sparingly
Every `friend` declaration is a small crack in encapsulation — it lets code outside the class reach into its internals. Used deliberately (an `operator<<`, a tightly coupled helper class, a unit test fixture), it's a reasonable, well-understood tool. Reached for too often, it defeats the entire point of marking things `private` in the first place. If you find yourself adding many friends to a class, it's often a sign the class's public interface should be redesigned instead.
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.