C++ Friend Functions
A C++ friend function is a non-member function that a class allows to access its private and protected members. It is useful when an operation belongs outside the class but still needs controlled access to the class’s internal data.
Friend functions should be used carefully. They can be helpful for operations involving two objects, stream operators, or utility functions, but too many friends can weaken encapsulation.
Basic Syntax
To make a function a friend, place a function declaration inside the class and begin it with the friend keyword. For example, a class could declare friend bool transfer(Account& from, Account& to, int amount);.
The function itself is still written outside the class, so it is not called with the dot operator and it does not have a this pointer. The friend declaration only grants access to private and protected members.
Example
This program uses a friend function to move money between two Account objects. The account balance stays private, but the friend function can read and update it directly.
#include <iostream>
#include <string>
class Account {
private:
std::string owner;
int balance;
public:
Account(std::string accountOwner, int startingBalance) {
owner = accountOwner;
balance = startingBalance;
}
void print() const {
std::cout << owner << ": $" << balance << std::endl;
}
friend bool transfer(Account& from, Account& to, int amount);
};
bool transfer(Account& from, Account& to, int amount) {
if (amount <= 0 || from.balance < amount) {
return false;
}
from.balance -= amount;
to.balance += amount;
return true;
}
int main(void) {
Account checking("Checking", 500);
Account savings("Savings", 200);
checking.print();
savings.print();
if (transfer(checking, savings, 150)) {
std::cout << "Transfer complete." << std::endl;
}
checking.print();
savings.print();
if (!transfer(savings, checking, 1000)) {
std::cout << "Transfer rejected." << std::endl;
}
return 0;
}
Output:
Checking: $500
Savings: $200
Transfer complete.
Checking: $350
Savings: $350
Transfer rejected.
How The Example Works
The Account class keeps owner and balance private. Normal outside code cannot write checking.balance or savings.balance.
The class declares transfer() as a friend. Because of that declaration, the function can read from.balance and update both account balances even though it is not a member function.
The function is a good fit as a non-member because a transfer involves two accounts equally. If it were a member function of one account, that account would feel like the only main object, even though both objects are part of the operation.
Friend Is Not A Class Member
A friend function is not inside the class’s public interface in the same way as a member function. You call it like an ordinary function, such as transfer(checking, savings, 150);.
You do not call it like a member function, such as checking.transfer(savings, 150);. The friend declaration only grants access. It does not make the function belong to the class.
When To Use Friend Functions
- Use a friend when a non-member function needs private access to do a clear job.
- Use a friend for operations that involve two objects equally.
- Use a friend for some operator overloads, especially when the left side is not your class.
- Avoid making helper functions friends when a public method would be simpler and safer.
Common Mistakes
- Thinking
friendmakes the function a member of the class. - Using friends to avoid designing a small public interface.
- Making many unrelated functions friends, which exposes too much of the class’s internals.
- Forgetting that friendship is granted by the class that owns the private data.
Takeaway: a friend function is a carefully chosen non-member function that can access private class data when that access makes the design clearer.
