由浅入深讲解动态类函数指针

1、首先描述一下指针值的含义: 

假设内存值的序列是这样描述的 : 我们定义一个 0 ~ 50 的正整数序列。

                                                       0,0,0,0,0,0,0,0,0,0,

                                                       0,0,0,0,1,0,0,8,0,0,

                                                       0,0,0,0,0,0,0,0,0,0,

                                                       0,0,0,0,0,0,0,0,0,0,

                                                       0,0,0,0,0,0,0,0,0,0

它第15号数值是 1,第18号数值是8。

由此,我们可以想象 “序号15” 就是指针,指针的值就是 “序号15位置上描述了一个变量1”。

为了方便表示:我们定义变量 x 的位置就在 “序号15”上,y序号的位置就在”序号18”上。

                                                        所以其值相加:x + y = 1 + 8 = 9;

为了刻意记录这些序号位置,我们又创建了一张表专门记录这些序号,它的描述方式假设是这样的:

(为了文章的简洁性:我们将描述这些变量的值 用 n(x) 来表式, & 表示向上取这些值的序号位置 )

                                          &n0  ,&n1  ,&n2  ,&n3  ,&n4  ,&n5  ,&n6  ,&n7  ,&n8  ,&n9 ,

                                          &n10,&n11,&n12,&n13,&n14,&n15,&n16,&n17,&n18,&n19,

                                          &n20,&n21,&n22,&n23,&n24,&n25,&n26,&n27,&n28,&n29,

                                          &n30,&n31,&n32,&n33,&n34,&n35,&n36,&n37,&n38,&n39,

                                          &n40,&n41,&n42,&n43,&n44,&n45,&n46,&n47,&n48,&n49

“序号15”位置上描述了一个变量1,我们可以理解成,记录 “序号15值”的变量是1,其变量名是”n15”,记录n15的位置是”&n15”(第15号地址);

因 ”&表示获取序号” ,那么它的反作用 ”*表示取序号下的值”所以:

                                                                                 *(&n15) = n15 = 1;

扩展理解【假设: *n15 = *(&1); (这里是把n15 的值当做一个地址来使用,它表示第1号地址的值)】

2、由于本文章强调的是动态函数指针传递,那么我们进入正题:(关于指针的其他问题可以在评论区提问)

//例子1 运行基本实例 (动态函数指针的传递)
class T_object
{
public:
	T_object(){
	}
	virtual ~T_object(){
	}
	int func(void* p){
		int step = *((int*)p);
		step += 2;
		return step;
	}
};

void main()
{
	T_object t;
	int (T_object::* _pfunc) (void*) = &T_object::func;
	int step = 0;
	for (size_t i = 0; i < 100; i++)
	{
		step = (t.*_pfunc)(&step);
		printf("running T_object::func,%d\n", step);
	}
}

将动态函数指针赋予 _pfunc 作为载体,它需要 t 对象完成实例化执行。

执行方法如下:

step = (t.*_pfunc)(&step); 
step = t.func(&step);

这两个等式表达方式是一样的。

(关于用途举例:可以在主类不采用多态的方式承载多套实现的方法,这里引用敲门砖,希望大家能够举一反三)

//例子2 动态函数指针的应用
class T_object
{
public:
	T_object(){
	}
	virtual ~T_object(){
	}
	int func(void* p){
		int step = *((int*)p);
		step += 2;
		return step;
	}
//new coode begin
	int func1(void* p) {
		int step = *((int*)p);
		step += 3;
		return step;
	}
	int func2(void* p) {
		int step = *((int*)p);
		step += 4;
		return step;
	}
//new coode end
};

void main()
{
	T_object t;
	int (T_object::* _pfunc) (void*) = &T_object::func;
	_pfunc = &T_object::func1;
	_pfunc = &T_object::func2;
	int step = 0;
	for (size_t i = 0; i < 100; i++)
	{
		step = (t.*_pfunc)(&step);
		printf("running T_object::func,%d\n", step);
	}
}

以上调用仅表示它最基本的原始代码展现,方便认知阅读:

(为了提高阅读使用性,下面我们开始优化变型操作)

将函数式包含在内,使调用方更易理解及调用;

//例子3 函数指针作为参数传递
class T_object
{
public:
	T_object(){
		m_pfunc = NULL;
	}
	virtual ~T_object() {
	}
	int func(void* p){
		int step = *((int*)p);
		step += 2;
		return step;
	}
	void addfunc(int(T_object::* pfunc)(void*))
	{
		m_pfunc = pfunc;
	}
	int Do(int step)
	{
		if (m_pfunc != NULL)
		{
			step = (this->*m_pfunc)(&step);
		}
		return step;
	}
	int(T_object::* m_pfunc)(void*);
};

void main()
{
	T_object t;
    //添加函数指针 (对外的方法及调用)
	t.addfunc(&T_object::func);
	int step = 0;
	for (size_t i = 0; i < 100; i++){
		step = t.Do(step);
		printf("running T_object::func,%d\n", step);
	}
}

根据此方法,可以动态的实施类函数的调用。

将函数指针式再简化,函数指针作为命名类型参数传递:

//例子 4 函数指针作为命名类型参数传递
class T_object
{
public:
	//定义函数类
	typedef int(T_object::* PFUNC)(void*);
	T_object() {
		m_pfunc = NULL;
	}
	virtual ~T_object() {
	}
	int func(void* p) {
		int step = *((int*)p);
		step += 2;
		return step;
	}
	void addfunc(PFUNC pfunc)
	{
		m_pfunc = pfunc;
	}
	int Do(int step)
	{
		if (m_pfunc != NULL)
		{
			step = (this->*m_pfunc)(&step);
		}
		return step;
	}
	PFUNC m_pfunc;
};
 
void main()
{
	T_object t;
    //添加函数指针 (对外的方法及调用)
	t.addfunc(&T_object::func);
	int step = 0;
	for (size_t i = 0; i < 100; i++){
		step = t.Do(step);
		printf("running T_object::func,%d\n", step);
	}
}

以上是关于类函数传参的调用方式,可以通过该方法实现很多功能,内容太多本次就不一一举例了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值