C ++ function pointer & class member function pointer

First, the function pointer

Functions are stored in the code area of ​​memory. They also have addresses. If we have an int test (int a) function, then its address is the name of the function. This is like an array. The name of an array is the starting point of the array. Start address.

1, the definition of function pointers
data_types (* func_pointer) (data_types arg1, data_types arg2, ..., data_types argn);

For example: int (* fp) (int a); // Here we define a pointer fp that points to a function (the function parameter is only an int type, and the function return value is an int type).

Examples

int test (int a)
{
     return a;
}
int main (int argc, const char * argv [])
{
    
     int (* fp) (int a);
     fp = test;
     cout << fp (2) << endl;
     return 0;
}

Note: The function pointed to by the function pointer must keep the function's return value type, the number of function parameters, and the type consistent.
2, typedef definition can simplify the definition of function pointers

Examples

int test (int a)
{
     return a;
}
 
int main (int argc, const char * argv [])
{
    
     typedef int (* fp) (int a);
     fp f = test;
     cout << f (2) << endl;
     return 0;
}

3.Function pointers can also be passed to functions as parameters

Examples

int test (int a)
{
     return a-1;
}
int test2 (int (* fun) (int), int b)
{
    
     int c = fun (10) + b;
     return c;
}
 
int main (int argc, const char * argv [])
{
    
     typedef int (* fp) (int a);
     fp f = test;
     cout << test2 (f, 1) << endl; // When calling test2, pass the address of the test function as a parameter to test2
     return 0;
}

Execute the above code, the output is: 10
4. Using function pointers, we can form an array of function pointers, or to be more specific, an array of pointers to functions.

Examples

void t1 () {cout << "test1" << endl;}
void t2 () {cout << "test2" << endl;}
void t3 () {cout << "test3" < * (instance object pointer) to call the function pointed to by the class member function pointer

Let's look at two examples:

A) Class member function pointers point to non-static member functions in the class

Take the address of a nonstatic member function to get the actual address of the function in memory

For a virtual function, its address is unknown at compile time, so for virtual member function (virtual member function) taking its address, all you can get is an index value

Examples

// Function pointer to class member function
#include
#include
using namespace std;
 
class A
{
     public:
         A (int aa = 0): a (aa) ()
 
         ~ A () {}
 
         void setA (int aa = 1)
         {
             a = aa;
         }
        
         virtual void print ()
         {
             cout << "A:" << a << endl;
         }
 
         virtual void printa ()
         {
             cout << "A1:" << a << endl;
         }
     private:
         int a;
};
 
class B: public A
{
     public:
         B (): A (), b (0) ()
        
         B (int aa, int bb): A (aa), b (bb) ()
 
         ~ B () {}
 
         virtual void print ()
         {
             A :: print ();
             cout << "B:" << b << endl;
         }
 
         virtual void printa ()
         {
             A :: printa ();
             cout << "B:" << b < * ptr) (1000);
 
     a.print ();
 
     (a. * ptr) (10000);
 
     a.print ();
     return 0;
}

Execute the above code, the output is:
A :: set (): 0x8048a38
B :: print (): 0x1
B :: print (): 0x5
A: 0
A: 10
A: 100
A: 1000
A: 10000

B) Class member function pointers point to static member functions in the class

Examples

#include
using namespace std;
 
class A {
public:
    
     // p1 is a function pointer to a non-static member function
     void (A :: * p1) (void);
    
     // p2 is a function pointer to a static member function
     void (* p2) (void);
    
     A () {
         /*Correct
          ** pointer to a non-static member function
          **with
          ** pointer to static member function
          The assignment method of ** variables is the same, both are of the form & ClassName :: memberVariable
          **The difference is that:
          ** Can only be assigned to non-static member functions for p1
          ** Only p2 can be assigned with a static member function
          **
          ** Furthermore, if the & memberVariable is directly assigned, "Compiler Error C2276" will be reported in VS
          ** See: http://msdn.microsoft.com/en-us/library/850cstw1.aspx
          * /
         p1 = & A :: funa; // Function pointer assignment must use &
         p2 = & A :: funb;
        
         // p1 = & A :: funb; // error
         // p2 = & A :: funa; // error
        
         // p1 = & funa; // error, compiler error C2276
         // p2 = & funb; // error, compiler error C2276
     }
    
     void funa (void) {
         puts ("A");
     }
    
     static void funb (void) {
         puts ("B");
     }
};
 
int main ()
{
     A a;
     // p is a function pointer to a non-static member function in A
     void (A :: * p) (void);
    
     (a. * a.p1) (); // Print A
    
     // Use. * (Instance object) or-> * (instance object pointer) to call the function pointed by the class member function pointer
     p = a.p1;
     (a. * p) (); // Print A
    
     A * b = & a;
     (b-> * p) (); // print A
    
     / * Although a.p2 itself is a non-static variable, a.p2 is a function pointer to a static function,
      ** So the following is wrong!
      * /
// p = a.p2; // error
    
     void (* pp) (void);
     pp = & A :: funb;
     pp (); // print B
    
     return 0;
}

to sum up

Class member function pointers are not the same as ordinary function pointers. The former uses the. * And-> * operators, while the latter can use the * operator (called "dereference" dereference, or "indirect").

Ordinary function pointers actually store the start address of the function body, so they are also called "code pointers" to distinguish them from the most commonly used data pointers in C / C ++.

The class member function pointer is not only the starting address of the memory of the class member function, but also needs to be able to solve the problem of adjusting the class instance address caused by multiple inheritance and virtual inheritance of C ++, so when the class member function pointer is called, Be sure to pass in a class instance object.

Author: