← Back to C++ Course | Chapter 8: OOP Core | Lesson 10 of 14

C++ Friend Functions

A friend is a function or class you trust enough to let see the private parts of your class, like giving a neighbor a spare key. It gets special access.
Syntax
cpp
class ClassName {
  friend return_type function_name(ClassName obj);
  friend class OtherClass;
};

Introduction to Friend Functions

A friend function is a function defined outside a class's own scope, but explicitly granted permission by that class to access its private and protected members.

It breaks strict encapsulation in a controlled, opt-in way, chosen by the class itself rather than forced from outside.

Example: Introduction to Friend Functions

cpp
#include <iostream>

class Box {
	int size = 5;
	friend void showSize(Box b);
};

void showSize(Box b) {
	std::cout << b.size << std::endl; // allowed: showSize is a friend
}

int main() {
	Box b;
	showSize(b);
	return 0;
}

Friend Class

A class can declare an entire other class as its friend.

When it does, every member function of that friend class gains access to the private and protected members of the class granting friendship, which is a much broader grant than befriending a single function.

Example: Friend Class

cpp
// Include std::cout and std::cin
#include <iostream>

// Define the type Engine
class Engine {
	// Declare power and set it to 100
	int power = 100;
	friend class Car;
};

// Define the type Car
class Car {
// Members below can be accessed from outside the class
public:
	void show(Engine e) { std::cout << e.power << std::endl; }
};

// Program execution starts in main()
int main() {
	Engine e;
	Car c;
	c.show(e);
	// Return 0 to signal that the program finished successfully
	return 0;
}

Friend Member Functions

Instead of making a whole other class a friend, you can grant friend status to just one specific member function of that class, giving it private access while keeping the rest of that class's methods locked out — a more surgical alternative to a full friend class.

Example: Friend Member Functions

cpp
// Include std::cout and std::cin
#include <iostream>

class Car;

// Define the type Mechanic
class Mechanic {
// Members below can be accessed from outside the class
public:
	void inspect(Car &c);
};

// Define the type Car
class Car {
	// Declare mileage and set it to 50000
	int mileage = 50000;
	friend void Mechanic::inspect(Car &c);
};

void Mechanic::inspect(Car &c) {
	// Print to the console with cout
	std::cout << c.mileage << std::endl;
}

// Program execution starts in main()
int main() {
	Car car;
	Mechanic m;
	m.inspect(car);
	// Return 0 to signal that the program finished successfully
	return 0;
}

Friend Functions with Multiple Classes

A single friend function can be declared a friend of multiple classes at once, letting it act as a bridge that reads or compares private data belonging to two different, otherwise-unrelated classes — useful for things like custom equality or arithmetic operators between two types.

Example: Friend Functions with Multiple Classes

cpp
// Include std::cout and std::cin
#include <iostream>

class Wallet;

// Define the type Bank
class Bank {
	// Declare reserve and set it to 1000
	int reserve = 1000;
	friend void compare(Bank b, Wallet w);
};

// Define the type Wallet
class Wallet {
	// Declare cash and set it to 50
	int cash = 50;
	friend void compare(Bank b, Wallet w);
};

void compare(Bank b, Wallet w) {
	// Print to the console with cout
	std::cout << (b.reserve > w.cash) << std::endl;
}

// Program execution starts in main()
int main() {
	Bank bank;
	Wallet wallet;
	compare(bank, wallet);
	// Return 0 to signal that the program finished successfully
	return 0;
}

Best Practices for Friend Functions

Friend declarations are convenient but should be used sparingly, since every friend you add is one more piece of code with direct access to your private internals.

Overusing them chips away at the very encapsulation that private and protected access specifiers exist to enforce.

Example: Best Practices for Friend Functions

cpp
#include <iostream>

class Box {
	int size = 5;
public:
	int getSize() { return size; } // prefer a public getter over a friend when possible
	friend void debugPrint(Box b); // reserved for genuinely tight-coupled cases only
};

void debugPrint(Box b) {
	std::cout << "Debug size: " << b.size << std::endl;
}

int main() {
	Box b;
	debugPrint(b);
	return 0;
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Assuming friendship is inherited or mutual, when it is neither.
  2. Overusing friend, which weakens encapsulation.
  3. Declaring a function as friend but never defining it, which causes a linker error.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.