Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Professional C++ [eng].pdf
Скачиваний:
284
Добавлен:
16.08.2013
Размер:
11.09 Mб
Скачать

Mastering Classes and Objects

person writing the class, but simpler for the person using the class. The point is to make your new classes as similar as possible to built-in types such as int and double: it’s easier to add objects using + than to remember whether the method name you should call is add() or sum().

Provide operator overloading as a service to clients of your class.

At this point, you might be wondering exactly which operators you can overload. The answer is “almost all of them — even some you’ve never heard of.” You have actually just scratched the surface: you’ve seen the assignment operator in the section on object life cycles, the basic arithmetic operators, the shorthand arithmetic operators, and the comparison operators. Overloading the stream insertion and extraction operators is also useful. In addition, there are some tricky, but interesting, things you can do with operator overloading that you might not anticipate at first. The STL uses operator overloading extensively. Chapter 16 explains how and when to overload the rest of the operators. Chapters 21 to 23 cover the STL.

Pointers to Methods and Members

Recall that you can create and use pointers to both variables and functions (if you need a refresher on pointers or function pointers, consult Chapter 13). Now, consider pointers to class members and methods. It’s perfectly legitimate in C++ to take the addresses of class members and methods in order to obtain pointers to them. However, remember that you can’t access a non-static member or call a non- static method without an object. The whole point of class members and methods is that they exist on a per-object basis. Thus, when you want to call the method or access the member via the pointer, you must dereference the pointer in the context of an object. Here is an example:

SpreadsheetCell myCell;

double (SpreadsheetCell::*methodPtr) () const = &SpreadsheetCell::getValue; cout << (myCell.*methodPtr)() << endl;

Don’t panic at the syntax. The second line declares a variable called methodPtr of type pointer to a const method that takes no arguments and returns a double. At the same time, it initializes this variable to point to the getValue() method of the SpreadsheetCell class. This syntax is quite similar to declaring a simple function pointer, except for the addition of SpreadsheetCell:: before the *methodPtr. That just means that this method pointer points to a method of the SpreadsheetCell class.

The second line calls the getValue() method (via the methodPtr pointer) on the myCell object. Note the use of parentheses surrounding cell.*methodPtr. They are needed because () has higher precedence than *.

Most of the time C++ programmers simplify the first line by using a typedef:

SpreadsheetCell myCell;

typedef double (SpreadsheetCell::*PtrToGet) () const;

PtrToGet methodPtr = &SpreadsheetCell::getValue; cout << (myCell.*methodPtr)() << endl;

217