Topic 47 of 91 8. Object-Oriented Programming in C++ Interactive Tutorial

Friend Functions and Friend Classes in C++: Controlled Access to Private Members

8 mins read Last updated: 26 Sep 2026 20,939 views

Direct Answer & Core Concept

A friend function or friend class is granted full access to private and protected members of the class that declares it. Friendship is declared using the friend keyword. It is primarily used for overloaded stream operators (operator<<, operator>>) and tightly coupled helper utility classes.

Detailed Explanation & Mechanics

1. Rules of Friendship:

  • Friendship is NOT symmetric: If Class A is a friend of Class B, Class B is not automatically a friend of Class A.
  • Friendship is NOT transitive: If A is a friend of B, and B is a friend of C, A is not a friend of C.
  • Friendship is NOT inherited: Derived classes do not inherit friend status.
Architecture Diagram
FRIEND ACCESS PRIVILEGES:
┌─────────────────────────────────────────────────────────────┐
│ class Matrix {                                              │
│   private: double data[4][4];                               │
│   friend class MatrixSolver; ──► MatrixSolver has full access│
│   friend std::ostream& operator

Runnable Code Example: Friend Functions and Friend Classes in C++

C++20 / C++23
main.cpp
Run Online
#include <iostream>

class ComplexNumber {
private:
    double real;
    double imag;

public:
    ComplexNumber(double r, double i) : real(r), imag(i) {}

    // Friend stream insertion operator
    friend std::ostream& operator<<(std::ostream& os, const ComplexNumber& c);

    // Friend helper function
    friend ComplexNumber add(const ComplexNumber& c1, const ComplexNumber& c2);
};

std::ostream& operator<<(std::ostream& os, const ComplexNumber& c) {
    os << c.real << " + " << c.imag << "i";
    return os;
}

ComplexNumber add(const ComplexNumber& c1, const ComplexNumber& c2) {
    // Direct access to private members 'real' and 'imag'
    return ComplexNumber(c1.real + c2.real, c1.imag + c2.imag);
}

int main() {
    ComplexNumber num1(3.5, 2.0);
    ComplexNumber num2(1.5, 4.5);
    ComplexNumber sum = add(num1, num2);

    std::cout << "Num 1: " << num1 << "\n";
    std::cout << "Num 2: " << num2 << "\n";
    std::cout << "Sum:   " << sum << "\n";
    return 0;
}

Common C++ Technical Interview Questions & Answers

Interview Prep
Q

Q: Why is overloading stream insertion `operator<<` typically done via a friend function?

A: The left operand of `std::cout << obj` is `std::ostream`, not our custom class. Thus `operator<<` cannot be a member function of our class and must be a non-member function granted friend access.

Key Takeaways, Modern Best Practices & Idioms

C++ Best Practices & Production Rules

• Limit friend declarations strictly to stream operators and tightly coupled unit test fixtures.
• Do not overuse friend classes, as excessive friendship breaks encapsulation and modularity.
• Declare friend functions inside the class body but implement them outside.
We value your privacy & transparency

OperateTools uses cookies and local storage to ensure basic tool functionality, preserve preferences, and analyze aggregated traffic. We never sell your personal data or index your document files. Learn more in our Privacy Policy.