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