<<
Ordinarily, the first parameter of an output operator is a reference to a nonconst ostream
object. The ostream
is nonconst
because writing to the stream changes its state. The parameter is a reference because we cannot copy an ostream
object.
The second parameter ordinarily should be a reference to const
of the class type we want to print. The parameter is a reference to avoid copying the argument. It can be const
because (ordinarily) printing an object does not change that object.
To be consistent with other output operators, operator<<
normally returns its ostream
parameter.
Sales_data
Output OperatorAs an example, we’ll write the Sales_data
output operator:
ostream &operator<<(ostream &os, const Sales_data &item)
{
os << item.isbn() << " " << item.units_sold << " "
<< item.revenue << " " << item.avg_price();
return os;
}
Except for its name, this function is identical to our earlier print
function (§ 7.1.3, p. 261). Printing a Sales_data
entails printing its three data elements and the computed average sales price. Each element is separated by a space. After printing the values, the operator returns a reference to the ostream
it just wrote.
The output operators for the built-in types do little if any formatting. In particular, they do not print newlines. Users expect class output operators to behave similarly. If the operator does print a newline, then users would be unable to print descriptive text along with the object on the same line. An output operator that does minimal formatting lets users control the details of their output.
Generally, output operators should print the contents of the object, with minimal formatting. They should not print a newline.
Input and output operators that conform to the conventions of the iostream
library must be ordinary nonmember functions. These operators cannot be members of our own class. If they were, then the left-hand operand would have to be an object of our class type:
Sales_data data;
data << cout; // if operator<< is a member of Sales_data
If these operators are members of any class, they would have to be members of istream
or ostream
. However, those classes are part of the standard library, and we cannot add members to a class in the library.
Thus, if we want to define the IO operators for our types, we must define them as nonmember functions. Of course, IO operators usually need to read or write the nonpublic
data members. As a consequence, IO operators usually must be declared as friends (§ 7.2.1, p. 269).
Exercise 14.6: Define an output operator for your Sales_data
class.
Exercise 14.7: Define an output operator for you String
class you wrote for the exercises in § 13.5 (p. 531).
Exercise 14.8: Define an output operator for the class you chose in exercise 7.40 from § 7.5.1 (p. 291).