由浅入深讲解动态类函数指针
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);
}
}
以上是关于类函数传参的调用方式,可以通过该方法实现很多功能,内容太多本次就不一一举例了。