怎样将成员函数指针强制转换成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 << ""<     }  

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

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

     void fun2(int nCount=1, ...)
     {
        cout << "I was fun2! nCount=" << nCount << " " <        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() <            cout << "I was fun2! while nCount=" << nCount << " = " << (char*)sum <            nCount--;  
        }

        va_end(args);

        //可变参数函数的传递
        fun3(1, args);
     }
     void fun3(int nCount=1, ...)
     {
        cout << "I was fun2! nCount=" << nCount << " " <        //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
void print(T Obj, MFP mfp, pCallFun pcf, Args... args)
{
    cout << "parameter Obj=" << Obj <<" mfp=" << mfp <<" pcf="<    cout << SZPARAM_NUM(0) << endl;
    // 定义成员函数指针类型
    //typedef void (AbstractMethod::*MFP)(void);
    std::map mapFn;

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

    //MFP mfp1 = &AbstractMethod::show;
    int64 * tmp =  (int64 *)&mfp1;    
    cout << " dec(十六进制) = "<    cout <<" mapFn.size() = " <
    PMS_CDP mfp2 = &AbstractMethod::fun;
    //MFP mfp2 = &AbstractMethod::fun;
    tmp = (int64*)&mfp2;
    cout <<" dec(十六进制) = "<< hex << *tmp  << " dec(十进制) = "<    mapFn.insert(make_pair("2",tmp));
    cout <<" mapFn.size() = " <
    PMS_GSS mfp3 = &AbstractMethod::fun1;
    //MFP mfp3 = &AbstractMethod::fun1;
    tmp = (int64 *)&mfp3;
    cout <<" dec(十六进制) = "<< hex << *tmp  << " dec(十进制) = "<    mapFn.insert(make_pair("3",tmp));
    cout <<" mapFn.size() = " <
    PMS_ARGS mfp4 = &AbstractMethod::fun2;
    //MFP mfp3 = &AbstractMethod::fun1;
    tmp = (int64 *)&mfp4;
    cout <<" dec(十六进制) = "<< hex << *tmp  << " dec(十进制) = "<    mapFn.insert(make_pair("4",tmp));
    cout <<" mapFn.size() = " <
    //key=string value=vector<>*
    vector  mapvs;
    mapvs.push_back("a");
    mapvs.push_back("b");
    vector  mapvs2;
    mapvs2.push_back("2a");
    mapvs2.push_back("2b");
    map* >  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




你可能感兴趣的:(C++11)