The pointer to member functions in C++ is a special concept. Basically, this is somewhat different concept from an ordinary pointer.
An ordinary pointer is a variable that just holds a physical address to some memory location. In this way, a pointer may point to either a variable or to a function.
However, the pointer to member functions cannot hold any physical address. Instead, these pointer-to-member hold an offset inside the class. Interestingly, there cannot be an address inside a class, an address can correspond to an object which resides in memory.
How compiler generates physical address
When the program combines such class offset with starting address of some object, then compiler generates a real address.
#include <iostream> //main header
using namespace std;//for namespace
class MainFunda
{
int iVal;
public:
void setiVal(int x) { iVal = x; }
int getiVal() { return iVal; }
};
int main()
{
void (MainFunda::*ptr2Func1)(int) = &MainFunda::setVal;
int (MainFunda::*ptr2Func2)() = &MainFunda::getVal;
MainFunda a; //Object
(a.*ptr2Func1)(5);
MainFunda *ptra = &a; //Pointer-to-object
int value = (ptra->*ptr2Func2)();
cout << "Value is : " << value << endl;
return 0;
}
The output is:
Value is: 5
The expression “a.*ptr2Func1” tells compiler to generate a physical address for this offset. Earlier, the compiler takes the address corresponds to object’s starting location in memory as base.
Using pointer to member for variable
To use a pointer to access data member, similar syntax can be used:
class MainFunda
{
public:
int iVal;
};
int (MainFunda::*ptr2data) = &MainFunda::val;
cout << (ptra->*ptr2data) << endl;
Incrementing and Decrementing pointers to members
Pointer to member functions in C++ are very special type of pointers. The compilers do not expect any tempering with such objects. Therefore, program should not manipulate them, like, incrementing or decrementing them, like ordinary pointers. Finally, the compiler shall throw an error in such statements.
#include //main header
using namespace std; //for namespace
class MainFunda
{
int iVal;
public:
void setiVal(int x) { iVal = x; }
int getiVal() { return iVal; }
};
int main()
{
void (MainFunda::*ptr2Func1)(int) = &MainFunda::setiVal;
int (MainFunda::*ptr2Func2)() = &MainFunda::getiVal;
ptr2Func1++;
ptr2Func2++;
return 0;
}
Output:
The compiler shall generate following message:
Similar error shall come on doing pre-increment or decrement of such pointers.
Pointer to member functions in C++ as function parameter
The program can pass pointer to member to function just like an ordinary pointer. Besides, there are 2 syntax to pass this:
Ordinary Syntax
void fun1( void(MainFunda::*p1)(int), MainFunda &ob1 )
{
(ob1.*p1)(11);
}
Typedef Syntax
This syntax creates a new typename. The following example shows that “PTR” is now a new “type”
typedef void (MainFunda::*PTR)(int);
void fun2( PTR p, MainFunda &ob1 )
{
(ob1.*p)(10);
}
The following program illustrates how to pass the pointer to member in both cases.
#include <iostream> //main header
using namespace std; //for namespace
class MainFunda
{
int iVal;
public:
void setiVal(int x) { iVal = x; }
int getiVal() { return iVal; }
};
//Ordinary syntax
void fun1( void(MainFunda::*p1)(int), MainFunda &ob1 )
{
(ob1.*p1)(11);
}
typedef void (MainFunda::*PTR)(int);
//Typedef syntax
void fun2( PTR p, MainFunda &ob1 )
{
(ob1.*p)(10);
}
int main()
{
void (MainFunda::*ptr2Func1)(int) = &MainFunda::setiVal;
MainFunda ob;
fun1( ptr2Func1, ob); //Passing to Ordinary Syntax
cout << ob.getiVal() << endl;
fun2( ptr2Func1, ob); //Passing to Typedef Syntax
cout << ob.getiVal() << endl;
return 0;
}
Output:
Related Topics: