7.1.3. Defining Nonmember Class-Related Functions

Image

Class authors often define auxiliary functions, such as our add, read, and print functions. Although such functions define operations that are conceptually part of the interface of the class, they are not part of the class itself.

We define nonmember functions as we would any other function. As with any other function, we normally separate the declaration of the function from its definition (§ 6.1.2, p. 206). Functions that are conceptually part of a class, but not defined inside the class, are typically declared (but not defined) in the same header as the class itself. That way users need to include only one file to use any part of the interface.


Image Note

Ordinarily, nonmember functions that are part of the interface of a class should be declared in the same header as the class itself.


Defining the read and print Functions

The read and print functions do the same job as the code in § 2.6.2 (p. 75) and not surprisingly, the bodies of our functions look a lot like the code presented there:

// input transactions contain ISBN, number of copies sold, and sales price
istream &read(istream &is, Sales_data &item)
{
    double price = 0;
    is >> item.bookNo >> item.units_sold >> price;
    item.revenue = price * item.units_sold;
    return is;
}
ostream &print(ostream &os, const Sales_data &item)
{
    os << item.isbn() << " " << item.units_sold << " "
       << item.revenue << " " << item.avg_price();
    return os;
}

The read function reads data from the given stream into the given object. The print function prints the contents of the given object on the given stream.

However, there are two points worth noting about these functions. First, both read and print take a reference to their respective IO class types. The IO classes are types that cannot be copied, so we may only pass them by reference (§ 6.2.2, p. 210). Moreover, reading or writing to a stream changes that stream, so both functions take ordinary references, not references to const.

The second thing to note is that print does not print a newline. Ordinarily, functions that do output should do minimal formatting. That way user code can decide whether the newline is needed.

Defining the add Function

The add function takes two Sales_data objects and returns a new Sales_data representing their sum:

Sales_data add(const Sales_data &lhs, const Sales_data &rhs)
{
    Sales_data sum = lhs;  // copy data members from lhs into sum
    sum.combine(rhs);      // add data members from rhs into sum
    return sum;
}

In the body of the function we define a new Sales_data object named sum to hold the sum of our two transactions. We initialize sum as a copy of lhs. By default, copying a class object copies that object’s members. After the copy, the bookNo, units_sold, and revenue members of sum will have the same values as those in lhs. Next we call combine to add the units_sold and revenue members of rhs into sum. When we’re done, we return a copy of sum.


Exercises Section 7.1.3

Exercise 7.6: Define your own versions of the add, read, and print functions.

Exercise 7.7: Rewrite the transaction-processing program you wrote for the exercises in § 7.1.2 (p. 260) to use these new functions.

Exercise 7.8: Why does read define its Sales_data parameter as a plain reference and print define its parameter as a reference to const?

Exercise 7.9: Add operations to read and print Person objects to the code you wrote for the exercises in § 7.1.2 (p. 260).

Exercise 7.10: What does the condition in the following if statement do?

if (read(read(cin, data1), data2))


..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.137.167.195