Professional C__ - Marc Gregoire [94]
MORE ABOUT METHODS
C++ also provides myriad choices for methods. This section explains all the tricky details.
static Methods
Methods, like members, sometimes apply to the class as a whole, not to each object. You can write static methods as well as members. As an example, consider the SpreadsheetCell class from Chapter 6. It has two helper methods: stringToDouble() and doubleToString(). These methods don’t access information about specific objects, so they could be static. Here is the class definition with these methods static:
class SpreadsheetCell
{
// Omitted for brevity
protected:
static string doubleToString(double val);
static double stringToDouble(const string& str);
// Omitted for brevity
};
Code snippet from SpreadsheetCellMethods\SpreadsheetCell.h
These methods are not declared as const anymore because it’s not allowed to declare static methods as const. The non-static versions of those methods were marked as const.
The implementations of these two methods are identical to the previous implementations. You don’t repeat the static keyword in front of the method definitions. However, note that static methods are not called on a specific object, so they have no this pointer, and are not executing for a specific object with access to its non-static members. In fact, a static method is just like a regular function. The only difference is that it can access private and protected static data members of the class. It can also access private and protected non-static data members on other objects of the same type, if those other objects are made visible to the static method, for example by passing in a reference or pointer to such object.
You call a static method just like a regular function from within any method of the class. Thus, the implementation of all methods in SpreadsheetCell can stay the same. Outside of the class, you need to qualify the method name with the class name using the scope resolution operator (as for static members). Access control applies as usual.
You might want to make stringToDouble() and doubleToString() public so that other code outside the class could make use of them. If so, you could call them from anywhere like this:
string str = SpreadsheetCell::doubleToString(5);
const Methods
A const object is an object whose value cannot be changed. If you have a const, reference to const or pointer to const object, the compiler will not let you call any methods on that object unless those methods guarantee that they won’t change any data members. The way you guarantee that a method won’t change data members is to mark the method itself with the const keyword. Here is the SpreadsheetCell class with the methods that don’t change any data member marked const:
class SpreadsheetCell
{
public:
// Omitted for brevity
double getValue() const;
string getString() const;
// Omitted for brevity
};
Code snippet from SpreadsheetCellMethods\SpreadsheetCell.h
The const specification is part of the method prototype and must accompany its definition as well:
double SpreadsheetCell::getValue() const
{
return mValue;
}
string SpreadsheetCell::getString() const
{
return mString;
}
Code snippet from SpreadsheetCellMethods\SpreadsheetCell.h
Marking a method as const signs a contract with client code guaranteeing that you will not try to change the internal values of the object within the method. If you try to declare a method const that actually modifies a data member, the compiler will complain. You also cannot declare a static method const because it is redundant. Static methods do not have an instance of the class so it would be impossible for them to change internal values. const works by making it appear inside the method that you have a const reference to each data member. Thus, if you try to change the data member the compiler will flag an error.
A non-const object can call const and non-const methods. However, a const object can only call const methods. Here are some examples:
SpreadsheetCell myCell(5);
cout << myCell.getValue() << endl; // OK
myCell.setString("6");