Professional C__ - Marc Gregoire [74]
Accessing Data Members
Most methods of a class, such as setValue() and getValue(), are always executed on behalf of a specific object of that class (the exceptions are static methods, which are discussed later). Inside the method body, you have access to all the data members of the class for that object. In the previous definition for setValue(), the following line changes the mValue variable inside whatever object calls the method:
mValue = inValue;
If setValue() is called for two different objects, the same line of code (executed once for each object) changes the variable in two different objects.
Calling Other Methods
You can call methods of a class from inside another method. For example, consider an extension to the SpreadsheetCell class. Real spreadsheet applications allow text data as well as numbers in the cells. When you try to interpret a text cell as a number, the spreadsheet tries to convert the text to a number. If the text does not represent a valid number, the cell value is ignored. In this program, strings that are not numbers will generate a cell value of 0. Here is a first stab at a class definition for a SpreadsheetCell that supports text data:
#include using std::string; class SpreadsheetCell { public: void setValue(double inValue); double getValue() const; void setString(string inString); string getString() const; protected: string doubleToString(double inValue) const; double stringToDouble(string inString) const; double mValue; string mString; }; Code snippet from SpreadsheetCellNumText\SpreadsheetCell.h This version of the class stores both text and numerical representations of the data. If the client sets the data as a string, it is converted to a double, and a double is converted to a string. If the text is not a valid number, the double value is 0. This class definition shows two new methods to set and retrieve the text representation of the cell and two new protected helper methods to convert a double to a string and vice versa. These helper methods use string streams, which are covered in detail in Chapter 15. Here are the implementations of all the methods. #include "SpreadsheetCell.h" #include #include using namespace std; void SpreadsheetCell::setValue(double inValue) { mValue = inValue; mString = doubleToString(mValue); } double SpreadsheetCell::getValue() const { return mValue; } void SpreadsheetCell::setString(string inString) { mString = inString; mValue = stringToDouble(mString); } string SpreadsheetCell::getString() const { return mString; } string SpreadsheetCell::doubleToString(double inValue) const { ostringstream ostr; ostr << inValue; return ostr.str(); } double SpreadsheetCell::stringToDouble(string inString) const { double temp; istringstream istr(inString); istr >> temp; if (istr.fail() || !istr.eof()) { return 0; } return temp; } Code snippet from SpreadsheetCellNumText\SpreadsheetCell.cpp Note that each of the set methods calls a helper method to perform a conversion. With this technique, both mValue and mString are always valid. The this Pointer Every normal method call passes a pointer to the object for which it is called as a “hidden” parameter with the name this. You can use this pointer to access data members or call methods, and can pass it to other methods or functions. It is also sometimes useful for disambiguating names. For example, you could have defined the SpreadsheetCell class with a value data member instead of mValue and you could have defined the setValue() method to take a parameter named value instead of inValue. In that case, setValue() would look like this: void SpreadsheetCell::setValue(double value) { value = value; // Ambiguous! mString = doubleToString(value); } Code snippet from SpreadsheetCellThis\ambiguous\SpreadsheetCell.cpp