C++:函数指针进阶(二):指向对象成员函数的指针

1:普通函数函数指针定义

我们知道 指向普通函数的指针,一般这么定义 :

数据类型名 (* 指针变量名)(参数列表)

void (*func)(int)

或者前面加一个  typedef 

typedef 数据类型名(*指针变量名)(参数列表)

typedef void (*funv) (int)

这两种方式都可以,但是建议使用第二种方式:因为第二种方式相当于给 函数指针定义了一个别名,能隐藏笨拙的语法构造以及平台一些相关的数据类型,可以使得代码更美观,可维护性、可移植性、可读性更强。

实例:

如果不带 typedef 关键字

//定义一个函数
void tech(void) { printf("tech dreamer"); }
void main()
{
    //定义一个指针,指针的名字叫func,它可以指向一个函数,并通过函数指针调用该函数
    void (*func)();
    func = &tech; // 将func()函数的入口地址赋给指针变量pf,所以,pf就指向func()函数
    func();        //第一种调用方式,带参数也可以
    (*func)();     //第二种调用方式,带参数也可以
}

增加 typedef 关键字 

void tech(void) { printf("tech dreamer"); }
//命名一个类型,那么这个时候func不可以直接调用,而是一个类型了
typedef void (*func)();
void main()
{
    //定义一个可调用的指针变量(函数):myfunc (这个是主要区别)
    func myfunc;
    myfunc = &tech; //将func()函数的入口地址赋给指针变量pf,所以,pf就指向func()函数
    myfunc();         //第一种调用方式,带参数也可以
    (*myfunc)();      //第二种调用方式,带参数也可以
}

2:对象成员函数函数指针定义

标题1介绍了,普通函数函数指针的定义,对象成员函数指针定义情况相比要复杂一些。 那么复杂在哪里了?

首先成员函数和普通函数的根本区别是:成员函数是类中的一个成员,编译系统要求在指针赋值语句中,指针变量的类型必须与赋值右侧函数的类型相匹配,具体以下三个方面需匹配。

  1. 函数参数的类型和参数的个数要匹配
  2. 函数返回值要匹配
  3. 函数所属的类要匹配

所以定义指向公用的 成员函数的指针变量操作步骤为:

1:定义形式:数据类型名 (类名::   *指针变量名)(参数列表)

2: 函数指针赋值: 指针变量名 = &类名::成员函数名

可以让它指向一个公用成员函数,只需要把公用成员函数的入口地址赋值给一个指向公用成员函数的指针变量即可。

3:函数调用:(对象名.*函数指针变量名)()

思考:这样定义的函数指针变量,指向了一个类中的一个函数。但是,当一个类实例化为多个对象的时候,到底要怎样使用该函数指针?函数指针指向哪一个对象函数,所以,我们在调用函数指针的时候,就必须指定哪一个对象。看下面这个例子:

// main.cpp


#include<iostream>
#include<string>
class  Student
{
public:
	// 定义成员变量
	char name[32];
	char addr[32];
	long number;

	Student(char* pn, char* pa, long n) {
		strcpy_s(name, pn);
		strcpy_s(addr, pa);
		number = n;
	}

	void print() {
		std::cout << "name = " << name << std::endl;
		std::cout << "addr = " << addr << std::endl;
		std::cout << "number = " << number << std::endl;
	}

private:

};
// 定义Student类中的一个函数指针
void(Student::* pFunc)();

int main(void) {
	std::string name = "xiaoming";
	std::string addr = "wuhan";
	Student stu((char*)name.c_str(),(char*)addr.c_str(), 123456789);

	// 给函数指针赋值
	pFunc = &Student::print;
	// 通过函数指针调用成员函数(且必须指定具体类对象)
	(stu.*pFunc)();
	return 0;
}


// 打印结果
name = xiaoming
addr = wuhan
number = 123456789

这里有个知识点:大家可以好好体会。

对象的成员函数不是存放在对象的空间中的,而是存放在对象外的空间中。如果有多个同类的对象,他们公用同一个函数代码段(类的成员函数),那么他们不是属于某一个对象,而是属于该类,由所有的类对象共享。因此,Student类中的 print()成员函数,不是属于stu对象的,而是属于 Student类。所以,给指针变量 pFunc赋值的地址,应该是Student类公用的函数代码段的入口地址。

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值