1. Function Pointers

Functions are stored in the code area of memory, and they also have addresses. If we have aint test(int a)function, then its address is the function name. This is just like an array, where the array name is the starting address of the array.

1.1 Definition of Function Pointers

data_types (*func_pointer)( data_types arg1, data_types arg2, ...,data_types argn);

For example:

int (*fp)(int a); // 这里就定义了一个指向函数(这个函数参数仅仅为一个 int 类型,函数返回值是 int 类型)的指针 fp。

Example

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 a function pointer must have the same return type, the same number of parameters, and the same parameter types.

1.2 Using typedef Can Simplify the Definition of Function Pointers

Example

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; }

1.3 Function Pointers Can Also Be Passed as Arguments to Functions

Example

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, the address of the test function is passed as an argument to test2 return 0; }

Executing the above code, the output is:

10

1.4 Using Function Pointers, We Can Construct an Array of Function Pointers, More Precisely an Array of Pointers to Functions

Example

void t1(){cout<<"test1"<<endl;} void t2(){cout<<"test2"<<endl;} void t3(){cout<<"test3"<<endl;} int main(int argc, const char * argv[]) { typedef void (*fp)(void); fp b[] = {t1,t2,t3}; // b[] is an array of pointers to functions b[0](); // Using subscript operations on the array of pointers to functions enables indirect calls to functions return 0; }

2. Function Pointers Pointing to Class Member Functions

Definition:A class member function pointer is a type of pointer data type in the C++ language, used to store access information for a member function of a specified class that has a given parameter list and return type.

Basically, there are two points to note:

  • 1. When assigning a function pointer, you must use&
  • 2. Use.*(instance object) or->*(instance object pointer) to call the function pointed to by the class member function pointer.

Let's look at two examples below:

A) Class Member Function Pointers Pointing to Non-static Member Functions in a Class

Fornonstatic member functiontaking its address obtains the actual address of the function in memory.

Forvirtual function, its address is unknown at compile time, so for a virtual member function, taking its address can only obtain an index value.

Example

// Function pointer pointing to a class member function #include <iostream> #include <cstdio> 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 << endl; } private: int b; }; int main(void) { A a; B b; void (A::*ptr)(int) = &A::setA; A* pa = &a; // For non-virtual functions, returns its real address in memory printf("A::set(): %p\n", &A::setA); // For virtual functions, returns its offset position in the virtual function table printf("B::print(): %p\n", &A::print); printf("B::print(): %p\n", &A::printa); a.print(); a.setA(10); a.print(); a.setA(100); a.print(); // For a function pointer pointing to a class member function, the this pointer of a class object must be passed when referencing, so it must be called by a class instance (pa->*ptr)(1000); a.print(); (a.*ptr)(10000); a.print(); return 0; }

Executing 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 Pointing to Static Member Functions in a Class

Example

#include <iostream> using namespace std; class A{ public: // p1 is a function pointer pointing to a non-static member function void (A::*p1)(void); // p2 is a function pointer pointing to a static member function void (*p2)(void); A(){ /*For **pointers to non-static member functions **and **pointers to static member functions **the assignment method is the same, both in the form &ClassName::memberVariable **The difference is: **p1 can only be assigned with non-static member functions **p2 can only be assigned with static member functions ** **Furthermore, when assigning, if you directly use &memberVariable, VS will report "Compiler Error C2276" **See: http://msdn.microsoft.com/zh-cn/library/850cstw1.aspx*/ p1 =&A::funa; // When assigning a function pointer, you 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 pointing to a non-static member function in A void (A::*p)(void); (a.*a.p1)(); // Prints A // Use .* (instance object) or ->* (instance object pointer) to call the function pointed to by the class member function pointer p = a.p1; (a.*p)();// Prints A A *b = &a; (b->*p)(); // Prints A /*Although a.p2 itself is a non-static variable, a.p2 is a function pointer pointing to a static function, **so the following sentence is wrong!*/ // p = a.p2;//error void (*pp)(void); pp = &A::funb; pp(); // Prints B return 0; }

Summary

Class member function pointers and ordinary function pointers are not the same thing. The former must use.*and ->*operator to use, while the latter can use*operator (called "dereference", or "indirection").

Ordinary function pointers actually store the starting 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++.

Class member function pointers, however, are not just the starting memory address of the class member function; they also need to solve the problem of adjusting the class instance address caused by C++ multiple inheritance and virtual inheritance. Therefore, when calling a class member function pointer, a class instance object must be passed in.

Original address: https://blog.csdn.net/crayondeng/article/details/16868351