Professional C__ - Marc Gregoire [102]
const SpreadsheetCell& rhs);
friend const SpreadsheetCell operator-(const SpreadsheetCell& lhs,
const SpreadsheetCell& rhs);
friend const SpreadsheetCell operator*(const SpreadsheetCell& lhs,
const SpreadsheetCell& rhs);
friend const SpreadsheetCell operator/(const SpreadsheetCell& lhs,
const SpreadsheetCell& rhs);
// Omitted for brevity
};
Code snippet from OperatorOverloading\SpreadsheetCell.h
Here are the implementations. The only tricky aspect is remembering to check for division by zero. This implementation throws an exception if division by zero is detected:
const SpreadsheetCell operator-(const SpreadsheetCell& lhs,
const SpreadsheetCell& rhs)
{
SpreadsheetCell newCell;
newCell.set(lhs.mValue - rhs.mValue); // update mValue and mString.
return newCell;
}
const SpreadsheetCell operator*(const SpreadsheetCell& lhs,
const SpreadsheetCell& rhs)
{
SpreadsheetCell newCell;
newCell.set(lhs.mValue * rhs.mValue); // update mValue and mString.
return newCell;
}
const SpreadsheetCell operator/(const SpreadsheetCell& lhs,
const SpreadsheetCell& rhs)
{
if (rhs.mValue == 0)
throw invalid_argument("Divide by zero.");
SpreadsheetCell newCell;
newCell.set(lhs.mValue / rhs.mValue); // update mValue and mString
return newCell;
}
Code snippet from OperatorOverloading\SpreadsheetCell.cpp
C++ does not require you to actually implement multiplication in operator*, division in operator/, and so on. You could implement multiplication in operator/, division in operator+, and so forth. However, that would be extremely confusing, and there is no good reason to do so except as a practical joke. Whenever possible, stick to the commonly used operator meanings in your implementations.
In C++, you cannot change the precedence of operators. For example, * and / are always evaluated before + and -. The only thing user-defined operators can do is specify the implementation once the precedence of operations has been determined.
Overloading the Arithmetic Shorthand Operators
In addition to the basic arithmetic operators, C++ provides shorthand operators such as += and -=. You might assume that writing operator+ for your class provides operator+= also. No such luck. You have to overload the shorthand arithmetic operators explicitly. These operators differ from the basic arithmetic operators in that they change the object on the left-hand side of the operator instead of creating a new object. A second, subtler, difference is that, like the assignment operator, they generate a result that is a reference to the modified object.
The arithmetic operators always require an object on the left-hand side, so you should write them as methods, not as global functions. Here are the declarations for the SpreadsheetCell class:
class SpreadsheetCell
{
public:
// Omitted for brevity
SpreadsheetCell& operator+=(const SpreadsheetCell& rhs);
SpreadsheetCell& operator-=(const SpreadsheetCell& rhs);
SpreadsheetCell& operator*=(const SpreadsheetCell& rhs);
SpreadsheetCell& operator/=(const SpreadsheetCell& rhs);
// Omitted for brevity
};
Code snippet from OperatorOverloading\SpreadsheetCell.h
Here are the implementations:
SpreadsheetCell& SpreadsheetCell::operator+=(const SpreadsheetCell& rhs)
{
set(mValue + rhs.mValue); // Call set to update mValue and mString.
return *this;
}
SpreadsheetCell& SpreadsheetCell::operator-=(const SpreadsheetCell& rhs)
{
set(mValue - rhs.mValue); // Call set to update mValue and mString.
return *this;
}
SpreadsheetCell& SpreadsheetCell::operator*=(const SpreadsheetCell& rhs)
{
set(mValue * rhs.mValue); // Call set to update mValue and mString.
return *this;
}
SpreadsheetCell& SpreadsheetCell::operator/=(const SpreadsheetCell& rhs)
{
if (rhs.mValue == 0)
throw invalid_argument("Divide by zero.");
set(mValue / rhs.mValue); // Call set to update mValue and mString.
return *this;
}
Code snippet from OperatorOverloading\SpreadsheetCell.cpp
The shorthand arithmetic operators are combinations of the basic arithmetic and the assignment operators. With the above