Wikibooksβ

More C++ Idioms/Virtual Friend Function

Contents

Friend functions are often needed in C++. A canonical example is that of types that can be printed to output streams (e.g., std::cout). An overloaded left-shift operator function, which is often a friend, is needed to achieve seamless streaming capabilities. Friend functions are really an extension of the class's interface. However, friend functions in C++ can not be declared virtual and therefore no dynamic binding of friend functions is possible. Applying a friend function to an entire hierarchy of classes becomes awkward if an overloaded friend function is needed for every class in the hierarchy. This lack of support for dynamic binding makes it hard to justify that friend functions are in fact an extension of the class's interface. Virtual friend function idiom addresses this concern elegantly.

Virtual friend function idiom makes use of an extra indirection to achieve the desired effect of dynamic binding for friend functions. In this idiom, usually there is only one function that is a friend of the base class of the hierarchy and the friend function simply delegates the work to a helper member function that is virtual. The helper function is overridden in every derived class, which does the real job and the friend function just serves as a facade.

classBase{public:friendostream&operator<<(ostream&o,constBase&b);// ...protected:virtualvoidprint(ostream&o)const{...}};/* make sure to put this function into the header file */inlinestd::ostream&operator<<(std::ostream&o,constBase&b){b.print(o);// delegate the work to a polymorphic member function.returno;}classDerived:publicBase{protected:virtualvoidprint(ostream&o)const{...}};