C++ Friend Functions

Special functions that can access private and protected members

🤝 What are Friend Functions?

Friend functions are special functions that can access private and protected members of a class. They break encapsulation rules when needed for specific operations like operator overloading or external utility functions.


class Box {
private:
    int width;
public:
    Box(int w) : width(w) {}
    friend void showWidth(Box b);  // Friend declaration
};

void showWidth(Box b) {
    cout << "Width: " << b.width;  // Can access private member
}
                                    

Key Features:

✓ Access Private Data

✓ Not Class Members

✓ Break Encapsulation

Types of Friends

🔧

Friend Function

External function accessing private data

friend void display(Class obj);
📦

Friend Class

Entire class can access private members

friend class FriendClass;

Friend Method

Specific method from another class

friend void Other::method();

Operator Friends

Overload operators as friends

friend Point operator+(Point, Point);

🔹 Friend Function Example

Friend functions allow external functions special access to a class's private and protected members, bypassing normal encapsulation for specific needs. Declared with the friend keyword inside the class, they are not member functions but can access private data. For a Rectangle class with private length and width, a friend function calculateArea() can directly read these fields to compute and return the area (e.g., 50 for 10×5). This is useful for operations that involve multiple classes or require symmetric operator overloading, though it should be used sparingly to avoid breaking encapsulation.

#include <iostream>
using namespace std;

class Rectangle {
private:
    int length, width;

public:
    Rectangle(int l, int w) : length(l), width(w) {}
    
    // Friend function declaration
    friend int calculateArea(Rectangle rect);
    friend void displayDimensions(Rectangle rect);
};

// Friend function definition (outside class)
int calculateArea(Rectangle rect) {
    // Can access private members directly
    return rect.length * rect.width;
}

void displayDimensions(Rectangle rect) {
    cout << "Length: " << rect.length << endl;
    cout << "Width: " << rect.width << endl;
}

int main() {
    Rectangle r(10, 5);
    
    cout << "Area: " << calculateArea(r) << endl;
    displayDimensions(r);
    
    return 0;
}

Output:

Area: 50

Length: 10

Width: 5

🔹 Friend Class Example

A friend class grants all its methods access to another class's private and protected members, facilitating close collaboration between coupled classes. If Car declares Engine as a friend, then Engine methods can directly inspect private Car details like model ("Toyota") and power specs ("200 HP, V6"). This is ideal for tightly integrated components where separation would introduce complexity, such as engine diagnostics accessing internal car state. However, overuse can create tight coupling and reduce maintainability, so friend classes should be limited to cases where a strong logical relationship exists.

#include <iostream>
using namespace std;

class Engine {
private:
    int horsepower;
    string type;

public:
    Engine(int hp, string t) : horsepower(hp), type(t) {}
    
    // Car class is a friend
    friend class Car;
};

class Car {
private:
    string model;
    Engine engine;

public:
    Car(string m, int hp, string engineType) 
        : model(m), engine(hp, engineType) {}
    
    void showDetails() {
        cout << "Car: " << model << endl;
        // Can access Engine's private members
        cout << "Engine: " << engine.horsepower << " HP, " 
             << engine.type << endl;
    }
};

int main() {
    Car myCar("Toyota", 200, "V6");
    myCar.showDetails();
    
    return 0;
}

Output:

Car: Toyota

Engine: 200 HP, V6

🔹 Friend Operator Overloading

Friend functions are commonly used to overload operators for binary operations where the first operand is not an instance of the class. For a Complex number class, overloading operator+ as a friend allows expressions like 3 + c1, where the integer isn't a Complex object. The friend function can access private real and imag members of both operands to compute the sum, as shown with c3 = c1 + c2 resulting in "4 + 6i". This maintains natural syntax and symmetry, which wouldn't be possible with a member function alone.

#include <iostream>
using namespace std;

class Complex {
private:
    double real, imag;

public:
    Complex(double r = 0, double i = 0) : real(r), imag(i) {}
    
    // Friend operator functions
    friend Complex operator+(const Complex& c1, const Complex& c2);
    friend ostream& operator<<(ostream& out, const Complex& c);
    friend istream& operator>>(istream& in, Complex& c);
};

// Friend function definitions
Complex operator+(const Complex& c1, const Complex& c2) {
    return Complex(c1.real + c2.real, c1.imag + c2.imag);
}

ostream& operator<<(ostream& out, const Complex& c) {
    out << c.real << " + " << c.imag << "i";
    return out;
}

istream& operator>>(istream& in, Complex& c) {
    cout << "Enter real and imaginary parts: ";
    in >> c.real >> c.imag;
    return in;
}

int main() {
    Complex c1(3, 4);
    Complex c2(1, 2);
    Complex c3 = c1 + c2;
    
    cout << "c1 = " << c1 << endl;
    cout << "c2 = " << c2 << endl;
    cout << "c3 = c1 + c2 = " << c3 << endl;
    
    return 0;
}

Output:

c1 = 3 + 4i

c2 = 1 + 2i

c3 = c1 + c2 = 4 + 6i

🧠 Test Your Knowledge

What can friend functions access?