Ordinarily, we define the arithmetic and relational operators as nonmember functions in order to allow conversions for either the left- or right-hand operand (§ 14.1, p. 555). These operators shouldn’t need to change the state of either operand, so the parameters are ordinarily references to const
.
An arithmetic operator usually generates a new value that is the result of a computation on its two operands. That value is distinct from either operand and is calculated in a local variable. The operation returns a copy of this local as its result. Classes that define an arithmetic operator generally define the corresponding compound assignment operator as well. When a class has both operators, it is usually more efficient to define the arithmetic operator to use compound assignment:
// assumes that both objects refer to the same book
Sales_data
operator+(const Sales_data &lhs, const Sales_data &rhs)
{
Sales_data sum = lhs; // copy data members from lhs into sum
sum += rhs; // add rhs into sum
return sum;
}
This definition is essentially identical to our original add
function (§ 7.1.3, p. 261). We copy lhs
into the local variable sum
. We then use the Sales_data
compound-assignment operator (which we’ll define on page 564) to add the values from rhs
into sum
. We end the function by returning a copy of sum
.
Classes that define both an arithmetic operator and the related compound assignment ordinarily ought to implement the arithmetic operator by using the compound assignment.
Exercise 14.13: Which other arithmetic operators (Table 4.1 (p. 139)), if any, do you think Sales_data
ought to support? Define any you think the class should include.
Exercise 14.14: Why do you think it is more efficient to define operator+
to call operator+=
rather than the other way around?
Exercise 14.15: Should the class you chose for exercise 7.40 from § 7.5.1 (p. 291) define any of the arithmetic operators? If so, implement them. If not, explain why not.