11.13 POINTERS TO CLASS MEMBERS IN C


11.13 POINTERS TO CLASS MEMBERS IN C++

Instead of using the designated names for accessing class members, it is also possible in C++ to use pointers that point directly to the data members and the member functions of a class. Different syntax is used for creating such pointers for static and nonstatic class members, and, within each category, for data members and member functions. Such pointers can be dereferenced with the operators

     .* or ->* 

depending on whether we invoke the operator with respect to an object or with respect to a pointer to an object.

We will use the following example to illustrate how to set up pointers that point directly to class members:

 
//PointerDirectToMember.cc #include <iostream> #include <string> using namespace std; class Robot { int idNum; string owner; static int nextIdNum; public: Robot( string ownername); int getIdNum(); string getOwner(); static int getNextIdNum(); }; Robot::Robot( string name ) { idNum = getNextIdNum(); owner = name; } int Robot::getIdNum() { //(A) int Robot::* ptr_idNum = &Robot::idNum; //(B) return (*this).*ptr_idNum; //(C) } string Robot::getOwner() { //(D) string Robot::* ptr_owner = &Robot::owner; //(E) return this->*ptr_owner; //(F) } //initialization of the static //data member: int Robot::nextIdNum = 1; int Robot::getNextIdNum() { //(G) int* ptr_nextIdNum = &Robot::nextIdNum; //(H) return (*ptr_nextIdNum)++; //(I) } int main() { int (Robot::* pf_1)() = &Robot::getIdNum; //(J) string (Robot::* pf_2)() = &Robot::getOwner; //(K) int ( * pf_3)() = &Robot::getNextIdNum; //(L) Robot r1( "ariel" ) cout << (r1.*pf_1)() << " " << (r1.*pf_2)(); // 1 ariel //(M) cout << endl; Robot r2( "muriel" ); cout << (r2.*pf_1)() << " " << (r2.*pf_2)(); // 2 muriel cout << endl; Robot r3( "mercurial" ); cout << (r3.*pf_1)() << " " << (r3.*pf_2)(); // 3 mercurial cout << endl; cout << "Next available ID: " << (*pf_3)(); // 4 //(N) return 0; }

Examine the implementation we wrote for the function getIdNum() in line (A). The left-hand side of the statement in line (B), reproduced here for convenience,

     int Robot::* ptr_idNum = &Robot::idNum; 

declares the identifier ptr_idNum to be of type int Robot::*, that is a pointer to an int data member of class Robot. The right hand side makes this pointer point to the data member idNum. As mentioned earlier, the operators ‘.*’ and ‘->*’ can be used for dereferencing such a pointer depending on whether we invoke the operator with respect to an object or a pointer to the object. In the following statement in line (C) of the program

     return (*this).*ptr_idNum; 

we used the .* operator with respect to the object *this on which the function getIdNum() will be invoked.

To illustrate the use of the operator ‘->*,’ in the implementation code for the function getOwner() in line (D), in line (E) we have a declaration similar to what we showed earlier in line (B), but to access the owner data member, we now use the syntax

      this->*ptr_owner; 

in line (F). Note that the pointer ptr_owner is of type string Robot::*.

The syntax for setting up a pointer to a static data member is shown in the implementation for the static member function getNextIdNum() in line (G). The pointer ptr_nextIdNum is now of the type int*, as opposed to int Robot::*, as made evident by the declaration in line (H). Also, as line (I) shows, dereferencing such a pointer is like dereferencing any pointer.

This takes us to the subject of setting up pointers to nonstatic and static member functions. At the beginning of main(), we declared three function pointers in lines (J), (K), and (L). The function pointer pf_1 in line (J) is of type

     int (Robot::*)() 

which means that pf_1 can be used for pointing to any Robot class member function that returns an int and that takes a void argument. The function pointer pf_2 in line (K) is of type

     string (Robot::*)() 

This pointer can be used as a pointer for any Robot class member function that returns a string and that takes a void argument. Finally, the function pointer pf_3 in line (L) is of type

     int (*)() 

which means that this pointer can be used for pointing to any function—in our context any static function—that returns an int and that takes a void argument.

Note how each of these function pointers is initialized. The first two, pf_1 and pf_2, declared as pointers to nonstatic member functions, are initialized by the function names Robot::getIdNum and Robot::getOwner. The third, pf_3, declared as a pointer to a global function, is initialized by the static member function name Robot::getNextIdNum.

Also pay attention to the dereferencing of the function pointers in the rest of main(). The pointers to nonstatic member functions must be invoked on specific objects, as we show in line (M) of the program. On the other hand, pointers to static member function can be dereferenced as ordinary function pointers, as demonstrated by line (N).




Programming With Objects[c] A Comparative Presentation of Object-Oriented Programming With C++ and Java
Programming with Objects: A Comparative Presentation of Object Oriented Programming with C++ and Java
ISBN: 0471268526
EAN: 2147483647
Year: 2005
Pages: 273
Authors: Avinash Kak

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net