Professional C__ - Marc Gregoire [100]
Code snippet from OperatorOverloading\AddSecondAttempt\SpreadsheetCellTest.cpp
C++ allows you to write your own version of the plus sign, called the addition operator, to work correctly with your classes. To do that you write a method with the name operator+ that looks like this:
class SpreadsheetCell
{
public:
// Omitted for brevity
const SpreadsheetCell operator+(const SpreadsheetCell& cell) const;
// Omitted for brevity
};
Code snippet from OperatorOverloading\AddSecondAttempt\SpreadsheetCell.h
You are allowed to write spaces between operator and the plus sign. For example, instead of writing operator+, you can write operator +. This is true for all operators. This book adopts the style without spaces.
The definition of the method is identical to the implementation of the add() method:
const SpreadsheetCell
SpreadsheetCell::operator+(const SpreadsheetCell& cell) const
{
SpreadsheetCell newCell;
newCell.set(mValue + cell.mValue); // update mValue and mString.
return newCell;
}
Code snippet from OperatorOverloading\AddSecondAttempt\SpreadsheetCell.cpp
Now you can add two cells together using the plus sign as shown previously.
This syntax takes a bit of getting used to. Try not to worry too much about the strange method name operator+ — it’s just a name like foo or add. In order to understand the rest of the syntax, it helps to understand what’s really going on. When your C++ compiler parses a program and encounters an operator, such as +, -, =, or <<, it tries to find a function or method with the name operator+, operator-, operator=, or operator<<, respectively, that takes the appropriate parameters. For example, when the compiler sees the following line, it tries to find either a method in the SpreadsheetCell class named operator+ that takes another SpreadsheetCell object or a global function named operator+ that takes two SpreadsheetCell objects:
SpreadsheetCell aThirdCell = myCell + anotherCell;
Note that there’s no requirement that operator+ takes as a parameter an object of the same type as the class for which it’s written. You could write an operator+ for SpreadsheetCells that takes a Spreadsheet to add to the SpreadsheetCell. That wouldn’t make sense to the programmer, but the compiler would allow it.
Note also that you can give operator+ any return value you want. Operator overloading is a form of function overloading, and recall that function overloading does not look at the return type of the function.
Implicit Conversions
Surprisingly, once you’ve written the operator+ shown earlier, not only can you add two cells together, you can also add a cell to a string, a double, or an int!
SpreadsheetCell myCell(4), aThirdCell;
string str = "hello";
aThirdCell = myCell + str;
aThirdCell = myCell + 5.6;
aThirdCell = myCell + 4;
Code snippet from OperatorOverloading\AddSecondAttempt\SpreadsheetCellTest.cpp
The reason this code works is that the compiler does more to try to find an appropriate operator+ than just look for one with the exact types specified. The compiler also tries to find an appropriate conversion for the types so that an operator+ can be found. Constructors that take the type in question are appropriate converters. In the preceding example, when the compiler sees a SpreadsheetCell trying to add itself to double, it finds the SpreadsheetCell constructor that takes a double and constructs a temporary SpreadsheetCell object to pass to operator+. Similarly, when the compiler sees the line trying to add a SpreadsheetCell to a string, it calls the string SpreadsheetCell constructor to create a temporary SpreadsheetCell to pass to operator+.
This implicit conversion behavior is usually convenient. However, in the preceding example, it doesn’t really make sense to add a SpreadsheetCell to a string. You can prevent the implicit construction of a SpreadsheetCell from a string by marking that constructor with the explicit keyword:
class SpreadsheetCell
{
public:
SpreadsheetCell();
SpreadsheetCell(double initialValue);
explicit