They provide a degree of freedom in the interface design options.
Member fns and friend fns are equally privileged (100% vested). The major difference is that a friend function is called like "f(x)", while a member is called like "x.f()". Thus friend fns allow the class's designer to select the syntax that is deemed most readable, which lowers maintenance costs.
The major disadvantage of friend functions is that they require an extra line of code when you want dynamic binding. To get the effect of a virtual friend, the friend function should call a hidden (usually "protected:") virtual member fn; e.g., void f(Base& b) b.do_f(); . Derived classes override the hidden virtual member function ( void Derived::do_f()), not the friend function.