类的成员函数指针作为成员函数的形参

时间:2021-07-08 19:06:05
类的成员函数指针作为成员函数的形参


class CUserAutoData
{
public:
CUserAutoData();
~CUserAutoData();

int AddInfoNoSafe(int iUserID, c_string& strKey, int iAddCount = 1);

private:

int _SetData(int iUserID, c_string& strKey, int iValue, void (*_in_pfun)(int&, int)  );

static void _add(int& iOut, int iValue);
void _set(int& iOut, int iValue);
}

int CUserAutoData::AddInfoNoSafe(int iUserID, c_string& strKey, int iAddCount/* = 1*/)
{
_SetData(iUserID, strKey, iAddCount, _add); // 这个调用正常,_add 是static函数

_SetData(iUserID, strKey, iAddCount, _set); // 这个编译报错

_SetData(iUserID, strKey, iAddCount, CUserAutoData::_set); // 这个编译报错

return 0;
}



为什么传一个静态成员函数就可以,传一个成员函数就不行了?
报错提示:
 error C3867: “CUserAutoData::_set”: 函数调用缺少参数列表;请使用“&CUserAutoData::_set”创建指向成员的指针

9 个解决方案

#1


成员函数隐含有一this指针 类的成员函数指针作为成员函数的形参

#2


又是这个问题,是不是同一个人啊

你传参进去需要有实际意义的内存,函数只有被调用才会被分配,使用后被释放,被定义为静态,分配了静态内存,是可被访问的有意义的内存

#3


那我要使成员函数最为形参,应该怎么做呢?可以实现吗?

就是这句代码, _set是成员函数
_SetData(iUserID, strKey, iAddCount, _set); 

#4



这个要怎么改呢?



class CTest
{
public:
int test(void (CTest::*F)(int) );
void _set(int iValue);
};

int CTest::test(void (CTest::*F)(int) )
{
(*F)(1);
// 此处编译报错
// error C2171: “*”: “void (__thiscall CTest::* )(int)”类型的操作数非法
// error C2064: 项不会计算为接受 1 个参数的函数
return 0;
}

#5


不能将类得成员函数传给普通的函数,结构不一样,类得成员函数是8B,4B对象地址+4B偏移地址。
在前面加个static

#6


引用 4 楼 gucheng789 的回复:
这个要怎么改呢?



C/C++ code?



123456789101112131415161718

class CTest { public:     int test(void (CTest::*F)(int) );     void _set(int iValue); };   int CTest::test(void (CTest::*F)(int) ) { ……

去掉*F前的限定符

void (*F)(int)

#7


引用 4 楼 gucheng789 的回复:
这个要怎么改呢?

C/C++ code?123456789101112131415161718class CTest{public:    int test(void (CTest::*F)(int) );    void _set(int iValue);}; int CTest::test(void (CTest::*F)(int) ){    (*F)(1);    // 此处编译报错……


int CTest::test(void (CTest::*F)(int) f)
 {
     (this->*f)(1);//你没有形参名,只有类型
     //(*F)(1);
     // 此处编译报错
     // error C2171: “*”: “void (__thiscall CTest::* )(int)”类型的操作数非法
     // error C2064: 项不会计算为接受 1 个参数的函数
     return 0;
 }

#8


引用 楼主 gucheng789 的回复:
类的成员函数指针作为成员函数的形参

C/C++ code?12345678910111213141516171819202122232425262728class CUserAutoData{public:    CUserAutoData();    ~CUserAutoData();     int AddInfoNoSafe(int iUserID, c_st……

&CUserAutoData::_set 与 void (*_in_pfun)(int&, int)是不同的类型(void (CUserAutoData::*_in_pfun)(int&, int)),作为非静态成员函数的_set会隐匿地传入一个this指针,编译器可能会将其处理成这样:
 void CUserAutoData_set(CUserAutoData*,int&, int);
而在类体内的调用方式两个方式也是不同的:(this->*f)(//...)与(*f)(//...)或f(//...)
由于 _SetData函数的要求的函数指针形参不是批向本类的成员函数,没有this指针,不能在类体内访问本类的成员,而你给的实参_set是本类非静态成员函数,可能会访问本类的成员

#9


引用 7 楼 c_rrb 的回复:
引用 4 楼 gucheng789 的回复:这个要怎么改呢?

C/C++ code?123456789101112131415161718class CTest{public:    int test(void (CTest::*F)(int) );    void _set(int iValue);}; int CTest::test(void (CTest::*……

汗,这个说法有误://你没有形参名,只有类型

#1


成员函数隐含有一this指针 类的成员函数指针作为成员函数的形参

#2


又是这个问题,是不是同一个人啊

你传参进去需要有实际意义的内存,函数只有被调用才会被分配,使用后被释放,被定义为静态,分配了静态内存,是可被访问的有意义的内存

#3


那我要使成员函数最为形参,应该怎么做呢?可以实现吗?

就是这句代码, _set是成员函数
_SetData(iUserID, strKey, iAddCount, _set); 

#4



这个要怎么改呢?



class CTest
{
public:
int test(void (CTest::*F)(int) );
void _set(int iValue);
};

int CTest::test(void (CTest::*F)(int) )
{
(*F)(1);
// 此处编译报错
// error C2171: “*”: “void (__thiscall CTest::* )(int)”类型的操作数非法
// error C2064: 项不会计算为接受 1 个参数的函数
return 0;
}

#5


不能将类得成员函数传给普通的函数,结构不一样,类得成员函数是8B,4B对象地址+4B偏移地址。
在前面加个static

#6


引用 4 楼 gucheng789 的回复:
这个要怎么改呢?



C/C++ code?



123456789101112131415161718

class CTest { public:     int test(void (CTest::*F)(int) );     void _set(int iValue); };   int CTest::test(void (CTest::*F)(int) ) { ……

去掉*F前的限定符

void (*F)(int)

#7


引用 4 楼 gucheng789 的回复:
这个要怎么改呢?

C/C++ code?123456789101112131415161718class CTest{public:    int test(void (CTest::*F)(int) );    void _set(int iValue);}; int CTest::test(void (CTest::*F)(int) ){    (*F)(1);    // 此处编译报错……


int CTest::test(void (CTest::*F)(int) f)
 {
     (this->*f)(1);//你没有形参名,只有类型
     //(*F)(1);
     // 此处编译报错
     // error C2171: “*”: “void (__thiscall CTest::* )(int)”类型的操作数非法
     // error C2064: 项不会计算为接受 1 个参数的函数
     return 0;
 }

#8


引用 楼主 gucheng789 的回复:
类的成员函数指针作为成员函数的形参

C/C++ code?12345678910111213141516171819202122232425262728class CUserAutoData{public:    CUserAutoData();    ~CUserAutoData();     int AddInfoNoSafe(int iUserID, c_st……

&CUserAutoData::_set 与 void (*_in_pfun)(int&, int)是不同的类型(void (CUserAutoData::*_in_pfun)(int&, int)),作为非静态成员函数的_set会隐匿地传入一个this指针,编译器可能会将其处理成这样:
 void CUserAutoData_set(CUserAutoData*,int&, int);
而在类体内的调用方式两个方式也是不同的:(this->*f)(//...)与(*f)(//...)或f(//...)
由于 _SetData函数的要求的函数指针形参不是批向本类的成员函数,没有this指针,不能在类体内访问本类的成员,而你给的实参_set是本类非静态成员函数,可能会访问本类的成员

#9


引用 7 楼 c_rrb 的回复:
引用 4 楼 gucheng789 的回复:这个要怎么改呢?

C/C++ code?123456789101112131415161718class CTest{public:    int test(void (CTest::*F)(int) );    void _set(int iValue);}; int CTest::test(void (CTest::*……

汗,这个说法有误://你没有形参名,只有类型