怎样将成员函数指针强制转换成void*指针

采用取成员函数指针的地址的方法,先把指向成员函数指针的指针强制转化为别的类型,如unsigned*,当然同样可以通过此转化后的指针经过相反的变换来调用成员函数。于是乎要转化为void*的问题也随之可解,如下示例:
/* VS2003下编译运行 */
class AbstractMethod
{
public:
 virtual void show(){}  // = 0;  // 可以是纯虚函数,这里为了测试方便不使用纯虚函数!

 void fun()
 {
  cout << "I was called!" << endl;
 }

 void fun1()
 {
  cout << "I was called!" << endl;
 }
};

int main()
{
 // 定义成员函数指针类型
 typedef void (AbstractMethod::*MFP)(void);

 // 转化函数指针为别的指针
 MFP mfp1 = &AbstractMethod::show; 
 unsigned* tmp =  (unsigned*)&mfp1;
 cout << hex << *tmp << endl;

 MFP mfp2 = &AbstractMethod::fun;
 tmp = (unsigned*)&mfp2;
 cout << hex << *tmp << endl;

 MFP mfp3 = &AbstractMethod::fun1;
 tmp = (unsigned*)&mfp3;
 cout << hex << *tmp << endl;

 // 通过转化后的指针调用成员函数
 AbstractMethod am;
 MFP* addr = (MFP*)tmp;
 (am.*mfp3)();
 (am.*(*addr))();

 return 0;
}

验证上述方法取得的成员函数地址是否正确:
1. 在调试是查看临时变量函数指针的值和输出的是否一样。
2. 可以根据调试时的反汇编进行结果验证。

3. 最好的办法就是如上例子通过转化后的指针来调用成员函数。


#define SZPARAM_NUM(I) szParam##I


typedef long long int64;  
typedef unsigned long long uint64;
//
class AbstractMethod
{
public:
     virtual void show(const std::string str1)// = 0;  // 可以是纯虚函数,这里为了测试方便不使用纯虚函数!
     {
         cout << "I was show! " << str1 << ""<<endl;
     }  

     void fun(const std::string str1, std::string str2)
     {
      cout << "I was fun! " << str1<< " "<< str2<<endl;
     }

     void fun1(int n3)
     {
      cout << "I was fun1! " << n3 << ""<<endl;
     }

     void fun2(int nCount=1, ...)
     {
        cout << "I was fun2! nCount=" << nCount << " " <<endl;
        va_list args;
        void* vdS[nCount] = {};
        va_start(args, nCount);  
        while(nCount > 0)  
        {  
            //通过va_arg(args,int)依次获取参数的值  
            void* sum = va_arg(args, void*);
            
            vdS[nCount] = sum;
            printf("void* = %p vdS[%d]= %p\n", sum, nCount, vdS[nCount]);
            //std::string str1 = (char*)sum;
            //cout << "I was fun2! while" << nCount << " = " << str1.c_str() <<endl;
            cout << "I was fun2! while nCount=" << nCount << " = " << (char*)sum <<endl;
            nCount--;  
        }

        va_end(args);

        //可变参数函数的传递
        fun3(1, args);
     }
     void fun3(int nCount=1, ...)
     {
        cout << "I was fun2! nCount=" << nCount << " " <<endl;
        //fun2(nCount, ## __VA_ARGS__);        
     }
};
//
// #ifdef DEBUG
// #define EnterPWDN_PS(format, ...) fprintf(stdout, ">> "format"\n", ##__VA_ARGS__)
// #else
// #define LOG(format, ...)
// #endif
// #define debug(format, ...) fprintf(stderr, fmt, __VA_ARGS__)  
// #define debug(format, args...) fprintf (stderr, format, args)  
// #define debug(format, ...) fprintf (stderr, format, ## __VA_ARGS__)
//在调试环境下,LOG宏是一个变参输出宏,以自定义的格式输出;
//在发布环境下,LOG宏是一个空宏,不做任何事情。

typedef void (AbstractMethod ::*PMS_MD)(const std::string str1);
typedef void (AbstractMethod ::*PMS_CDP)(const std::string str1, std::string str2);
typedef void (AbstractMethod ::*PMS_GSS)(int n3);
typedef void (AbstractMethod ::*PMS_ARGS)(int nCount, ...);
#define EnterPWDN_PS(Obj, MFP, pCallFun, args...) (Obj.*(*(MFP*)pCallFun))(args);
#define EnterPWDN_P1(Obj, MFP, pCallFun, Args1) (Obj.*(*(MFP*)pCallFun))(Args1);
#define EnterPWDN_P2(Obj, MFP, pCallFun, Args1, Args2) (Obj.*(*(MFP*)pCallFun))(Args1, Args2);
/
 //递归终止函数
void print()
{
   cout << "empty" << endl;
}
//展开函数
template <class T, class MFP, class pCallFun, class ...Args>
void print(T Obj, MFP mfp, pCallFun pcf, Args... args)
{
    cout << "parameter Obj=" << Obj <<" mfp=" << mfp <<" pcf="<<pcf<<" typeinfo=" << typeid(T).name() << endl;
    //print(mfp,pcf,rest...);
    (Obj.*(*(MFP*)pcf))(args...);
}
//
int main(int argc, char* argv[])
{   
    string szParam0 = "avc";
    cout << SZPARAM_NUM(0) << endl;
    // 定义成员函数指针类型
    //typedef void (AbstractMethod::*MFP)(void);
    std::map<string, int64*> mapFn;

    // 转化函数指针为别的指针
    PMS_MD mfp1 = &AbstractMethod::show;

    //MFP mfp1 = &AbstractMethod::show;
    int64 * tmp =  (int64 *)&mfp1;    
    cout << " dec(十六进制) = "<<hex << *tmp << " dec(十进制) = "<<dec << *tmp<< " sizeof(void*) = "<< sizeof(void*) <<" sizeof(int64) = "<< sizeof(int64)<< endl;

    mapFn.insert(make_pair("1",tmp));
    cout <<" mapFn.size() = " <<mapFn.size()<<endl;

    PMS_CDP mfp2 = &AbstractMethod::fun;
    //MFP mfp2 = &AbstractMethod::fun;
    tmp = (int64*)&mfp2;
    cout <<" dec(十六进制) = "<< hex << *tmp  << " dec(十进制) = "<<dec << *tmp<< endl;
    mapFn.insert(make_pair("2",tmp));
    cout <<" mapFn.size() = " <<mapFn.size()<<endl;

    PMS_GSS mfp3 = &AbstractMethod::fun1;
    //MFP mfp3 = &AbstractMethod::fun1;
    tmp = (int64 *)&mfp3;
    cout <<" dec(十六进制) = "<< hex << *tmp  << " dec(十进制) = "<<dec << *tmp<< endl;
    mapFn.insert(make_pair("3",tmp));
    cout <<" mapFn.size() = " <<mapFn.size()<<endl;

    PMS_ARGS mfp4 = &AbstractMethod::fun2;
    //MFP mfp3 = &AbstractMethod::fun1;
    tmp = (int64 *)&mfp4;
    cout <<" dec(十六进制) = "<< hex << *tmp  << " dec(十进制) = "<<dec << *tmp<< endl;
    mapFn.insert(make_pair("4",tmp));
    cout <<" mapFn.size() = " <<mapFn.size()<<endl;

    //key=string value=vector<>*
    vector<string>  mapvs;
    mapvs.push_back("a");
    mapvs.push_back("b");
    vector<string>  mapvs2;
    mapvs2.push_back("2a");
    mapvs2.push_back("2b");
    map<string, vector<string>* >  mapTs;
    mapTs["1"] = &mapvs;
    mapTs["2"] = &mapvs2;


    //MFP* addr = (MFP*)nfn;
    //(am.*mfp3)();
    //(am.*(*addr))();

    // 通过转化后的指针调用成员函数
    AbstractMethod am;
    std::string strKey = "1";
    int64* nfn = mapFn[strKey];
    EnterPWDN_P1(am, PMS_MD, nfn, "1234");

    strKey = "2";
    nfn = mapFn[strKey];
    EnterPWDN_P2(am, PMS_CDP, nfn, "ab", "cd");

    strKey = "3";
    nfn = mapFn[strKey];
    EnterPWDN_P1(am, PMS_GSS, nfn, 456);

    strKey = "4";
    nfn = mapFn[strKey];
    std::string ss = "abc";
    printf("ss = %p\n", &ss);

    ST st;
    st.a = 1;
    st.b = 2;
    st.s = "st";
    printf("st = %p\n", &st);
    EnterPWDN_PS(am, PMS_ARGS, nfn, 2, (void*)&ss, (void*)&st);


    //biancan    
    //EnterPWDN_PS(1,2,3,4,5,6,7,"aaaa","bbbbb");
    //print(1,2,"a","bdc",ss);

    return 0;

}

输出结果:

avc
 dec(十六进制) = 1 dec(十进制) = 1 sizeof(void*) = 8 sizeof(int64) = 8
 mapFn.size() = 1
0x4029ce
0x4029ce
 dec(十六进制) = 4029ce dec(十进制) = 4205006
 mapFn.size() = 2
 dec(十六进制) = 402a32 dec(十进制) = 4205106
 mapFn.size() = 3
 dec(十六进制) = 402a7e dec(十进制) = 4205182
 mapFn.size() = 4
I was show! 1234
I was fun! ab cd
I was fun1! 456
ss = 0x7ffe9901f7a0
st = 0x7ffe9901f880
I was fun2! nCount=2
void* = 0x7ffe9901f7a0 vdS[2]= 0x7ffe9901f7a0
I was fun2! while nCount=2 = ����
void* = 0x7ffe9901f880 vdS[1]= 0x7ffe9901f880
I was fun2! while nCount=1 =
I was fun2! nCount=1




  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

隨意的風

如果你觉得有帮助,期待你的打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值