Sometimes it really becomes necessary to have access to the private data fields of your class from outside. In this case, no friends can not do.
Here is an example - you wrote a class describing a game unit. This class contains the internal representation of m_HP and the open interface Injure — cause damage, Heal — treat, and IsAlive — check whether the unit is alive.
class Unit { public: friend void TestUnit(); Unit(unsigned maxHP) : m_maxHP(maxHP) , m_HP(maxHP) {}; void Injure(unsigned val) { m_HP -= val; if( m_HP < 0 ) { m_HP = 0; } }; void Heal(unsigned val) { m_HP += val; if( m_HP > m_maxHP ) { m_HP = m_maxHP; } } bool IsAlive() const { return m_HP > 0; } private: unsigned m_maxHP; int m_HP; };
You decide to wrap the functionality of the class unit with tests, to be sure that the void Injure (unsigned val) and void Heal (unsigned val) functions work correctly:
void TestUnit() { Unit unit(100); unit.Injure(10); assert(unit.m_HP == 90); // check private data field unit.Heal(20); assert(unit.m_HP == 100); // check private data field } int main() { TestUnit(); }
As you can see, writing a test would be impossible without reference to the internal representation of the class. That is why we declared the void TestUnit () function to be class-friendly Unit
Upd:
Another example of the use of friendly functions in the design of its own class and ensure its functionality. Below is a very simple custom class wrapping an integer. To put instances of this class into the output stream, it is most natural to define the operator << function that is not an instance of the class.
#include <iostream> class WrappedInt { public: explicit WrappedInt(int val) : m_value(val) {} friend std::ostream& operator<<(std::ostream& os, const WrappedInt& val); private: int m_value; }; std::ostream& operator<<(std::ostream& os, const WrappedInt& val) { os << val.m_value; return os; }
and in order for this function to have access to the private fields of a class, such as m_value, we make it friendly to the WrappedInt class.