C++函数指针
机器学习入坑者 人气:01、指向函数的指针
函数的代码在内存中的首地址,是由函数名表示的,也就是说函数名等价于函数代码首地址。因此,可以定义一个指向函数的指针,即函数指针。函数指针定义和赋值的语法如下,其中数据类型代表指向函数的返回类型,形参表为指向函数的形参表;赋值时必须保证指向的函数名和函数指针的返回类型和形参完全相同:
数据类型 (*函数指针名)(形参表);
函数指针名 = 函数名;
下面的例子定义了一个函数和一个函数指针,通过函数指针调用函数代码:
/// 1、预先定义一个返回int类型的函数 int addOne(int x) { x = x + 1; return x; } /// 2、定义并赋值函数指针 int (*pointerAddOne)(int x); pointerAddOne = addOne; /// 3、使用函数指针和使用函数名的方式相同 data = pointerAddOne(data);
2、对象指针
顾名思义,对象指针表示指向对象的指针。对象名即对象的地址,所以可以将对象的地址赋值给同类型的指针,从而通过该指针使用此对象。
定义与使用对象指针包含4个步骤:
- 定义XXX类型指针;
- 定义XXX类型对象;
- 将对象地址赋值给指针;
- 使用“(*对象指针名).成员名”或者“对象指针名->成员名”的形式使用对象的成员;
下面的例子展示了对象指针的定义与使用:
Duck duck(666); /// 定义并赋值对象指针 Duck *pointerDuck; pointerDuck = &duck; /// 对象指针采用两种方式访问对象的成员 printf("%d \n", (*pointerDuck).getAge()); printf("%d \n", pointerDuck->getAge());
3、this指针
C++中,类的每个对象的数据成员都需要单独分配内存,但是类的所有对象的函数成员共享内存。this指针是对象的非静态成员函数的隐含参数,不需要自己进行定义,this指针指向当前调用非静态成员函数的对象。当类对象调用非静态成员函数时,对象的地址作为this指针的值,进而非静态成员函数通过this指向的地址,来访问对象的数据成员(类的不同对象的数据成员存储在不同的地址,this指针用于传递对象的地址)。
this指针访问其指向的对象数据成员的语法为:
this->数据成员名
下面的例子中,Duck类的成员函数getAge需要访问对象的数据成员duckAge,但是由于函数中已经存在同名的duckAge变量,所以需要通过this来访问数据成员duckAge
:
class Duck{ public: Duck(int age) { duckAge = age; }; int getAge() { int duckAge = 3; /// 通过this访问对象的数据成员duckAge,而不是局部变量duckAge return this->duckAge; }; private: int duckAge; };
4、指向类的非静态成员的指针
首先,类的静态成员和非静态成员是不同的,静态成员属于类,而非静态成员属于对象。指向类的非静态成员的指针,包含指向数据成员的指针和指向函数成员的指针。声明时需要指明指针指向的“类名”和“类型”,类型表示数据成员或函数成员的数据类型:
类型 类名::*数据成员指针名;
类型 (类名::*函数成员指针名)(参数表);
下面定义的Duck类包含public成员:int类型数据成员duckWeight和int类型函数成员getAge()(指向非静态成员的指针也必须遵守访问权限,不能指向private成员)下面分别声明指向二者的指针:
int Duck::*pointerDuckWeight; int (Duck::*pointerGetAge)();
指向非静态成员的数据指针和函数指针赋值语法为:
数据成员指针名 = &类名::数据成员名;
函数成员指针名 = &类名::函数成员名;
下面对两个指针进行赋值:
pointerDuckWeight = &Duck::duckWeight; pointerGetAge = &Duck::getAge;
上面进行的声明和赋值都是针对类进行的,所以并没有指向对象的成员地址。这里涉及到类的定义过程,类定义时并没有分配内存,而只是确定各个数据成员所占内存大小和相对位置。所以,可以使用对象的起始地址加相对位置对数据成员进行访问。非静态数据成员指针访问成员的语法有如下两种方式:
对象名.*数据成员的指针名
对象指针名->*数据成员指针名
/// 调用例子 printf("%d \n", duck.*pointerDuckWeight);
函数成员并不针对每个对象都有一个副本,而是共享的。对象调用函数成员时需要通过this指针,非静态成员函数指针的调用包含下面两种语法:
(对象名.函数成员指针名)(实参表)
(对象指针名->*函数成员指针名 )(实参表)
/// 实际调用的例子 printf("%d \n", (duck.*pointerGetAge)());
5、指向类的静态成员的指针
对于类的静态数据成员和函数成员,由于其并不属于具体的对象,所以只需要普通的数据型指针和函数型指针即可。
下面定义的Duck类包含用static声明的静态数据成员和静态函数成员:
class Duck{ public: static int getAge() { return 666; }; static int duckWeight; }; int Duck::duckWeight = 333;
下面是指向类的静态成员的数据型指针和函数型指针的定义和赋值过程:
int *pointerDuckWeight; int (*pointerGetAge)(); /// 赋值语法:指针名=&类名:静态成员名 pointerDuckWeight = &Duck::duckWeight; pointerGetAge = &Duck::getAge;
调用指针的时候,只需要遵守基本数据型指针和函数型指针的调用语法即可:
printf("%d \n", *pointerDuckWeight); printf("%d \n", (*pointerGetAge)());
加载全部内容