Up until this point, all the function pointers you've created have been for general, non-class functions. It is also possible to create pointers to functions that are members of classes.
To create a pointer to member function, use the same syntax as with a pointer to a function, but include the class name and the scoping operator (::). Thus, if pFunc points to a member function of the class Shape, which takes two integers and returns void, the declaration for pFunc is the following:
void (Shape::*pFunc) (int, int);
Pointers to member functions are used in exactly the same way as pointers to functions, except that they require an object of the correct class on which to invoke them. Listing 20.9 illustrates the use of pointers to member functions.
(0)Quit (1)Dog (2)Cat (3)Horse: 1 (1)Speak (2)Move: 1 Woof! (0)Quit (1)Dog (2)Cat (3)Horse: 2 (1)Speak (2)Move: 1 Meow! (0)Quit (1)Dog (2)Cat (3)Horse: 3 (1)Speak (2)Move: 2 Galloping (0)Quit (1)Dog (2)Cat (3)Horse: 0
On lines 5–14, the abstract data type Mammal is declared with two pure virtual methods, Speak() and Move(). Mammal is subclassed into Dog, Cat, and Horse, each of which overrides Speak() and Move(). |
The main() function asks the user to choose which type of animal to create, and then a new subclass of Animal is created on the free store and assigned to ptr on lines 49–63.
The user is then prompted for which method to invoke, and that method is assigned to the pointer pFunc. On line 79, the method chosen is invoked by the object created, by using the pointer ptr to access the object and pFunc to access the function.
Finally, on line 80, delete is called on the pointer ptr to return the memory set aside for the object to the heap. Note that there is no reason to call delete on pFunc because this is a pointer to code, not to an object on the heap. In fact, attempting to do so will generate a compile-time error.
As with pointers to functions, pointers to member functions can be stored in an array. The array can be initialized with the addresses of various member functions, and those can be invoked by offsets into the array. Listing 20.10 illustrates this technique.
(0)Quit (1)Speak (2)Move (3)Eat (4)Growl (5)Whimper (6)Roll Over (7)Play Dead: 1 Woof! (0)Quit (1)Speak (2)Move (3)Eat (4)Growl (5)Whimper (6)Roll Over (7)Play Dead: 4 Grrrrrr (0)Quit (1)Speak (2)Move (3)Eat (4)Growl (5)Whimper (6)Roll Over (7)Play Dead: 7 Is this the end of Little Caesar? (0)Quit (1)Speak (2)Move (3)Eat (4)Growl (5)Whimper (6)Roll Over (7)Play Dead: 0
On lines 3–14, the class Dog is created with seven member functions all sharing the same return type and signature. On line 16, a typedef declares PDF to be a pointer to a member function of Dog that takes no parameters and returns no values, and that is const: the signature of the seven member functions of Dog.
On lines 20–29, the array DogFunctions is declared to hold seven such member functions, and it is initialized with the addresses of these functions.
On lines 36 and 37, the user is prompted to pick a method. Unless he picks Quit, a new Dog is created on the heap, and then the correct method is invoked on the array on line 47. Here's another good line to show to any hotshot C++ programmers you know; ask them what this does:
(pDog->*DogFunctions[Method-1])();
Once again, this is a bit esoteric, but when you need a table built from member functions, it can make your program far easier to read and understand.
3.133.133.61