Friend functions and classes provide direct access to private and protected members of class to avoid breaking encapsulation in the general case. Most usage is with ostream: we would like to be able to type:
Point p;
cout << p;
However, this may require access to the private data of Point, so we define the overloaded operator
friend ostream& operator<<(ostream& output, const Point& p);
There are obvious encapsulation implications, however. First, now the friend class or function has full access to ALL members of the class, even ones that do not pertain to its needs. Second, the implementations of the class and the friend are now enmeshed to the point where an internal change in the class can break the friend.
If you view the friend as an extension of the class, then this is not an issue, logically speaking. But, in that case, why was it necessary to spearate out the friend in the first place.
To achieve the same thing that 'friends' purport to achieve, but without breaking encapsulation, one can do this:
class A
{
public:
void need_your_data(B & myBuddy)
{
myBuddy.take_this_name(name_);
}
private:
string name_;
};
class B
{
public:
void print_buddy_name(A & myBuddy)
{
myBuddy.need_your_data(*this);
}
void take_this_name(const string & name)
{
cout << name;
}
};
Encapsulation is not broken, class B has no access to the internal implementation in A, yet the result is the same as if we had declared B a friend of A. The compiler will optimize away the function calls, so this will result in the same instructions as direct access.
I think using 'friend' is simply a shortcut with arguable benefit, but definite cost.