If a class is not intended to be used as a base class, the I/O operators can be made friends of
the class. However, note that this approach reduces the possibilities significantly when inheritance
is used. Friend functions cannot be virtual; as a result, the wrong function might be called. For
example, if a reference to a base class refers to an object of a derived class and is used as an argument
for the input operator, the operator for the base class is called. To avoid this problem, derived classes
should not implement their own I/O operators. Thus, the implementation sketched previously is
more general than the use of friend functions and should be used as a standard approach, although
most examples use friend functions instead.