yang79tao()
的说法是错误的.线程函数,是需要一个函数指针,对这个函数指针的唯一要求是
它的类型必须符合要求.
因为这个指针要用来做线程启动函数(beginthread等)的参数,类型不符合肯定不行.
为了符合这个类型,函数我们按照一般格式定义就可以了.
成员函数的地址也是在编译的时候就确定了的.
只有成员变量,因为它属于对象,而对象是运行的时候创建的,所以成员变量的地址是运行时候才确定的.

解决方案 »

  1.   

    线程函数,是需要一个函数指针,对这个函数指针的唯一要求是它的类型必须符合要求.不能使用类成员函数原因在于C++的类在调用时,隐含传递了类的指针,例如
    Cxxx::func1(LPARAM lParam);
    实际调用时会被展开成 func1(pClass->this, lParam); 用汇编表示如下:
    push lParam
    push pClass->this
    call func1而一般的函数或类的静态成员函数调用时为
    push lParam
    call func1
      

  2.   

    签名符合要求这是肯定的了!这不用强调了吧?至于成员函数调用时隐含传递了this指针,刚好证明成员函数的地址是在运行时生成的,编译时只是一个相对地址!(其实任何地址都是相对地址,基本上。只是成员函数的这个相对地址是相对于所在的实例的,而全局函数的相对地址是相对于整个程序的)比如有个类A,则A a1, a2;
    那么a1与a2中的同一个成员函数的地址,怎么可能相同呢?
      

  3.   

    成员函数的地址在编译时也已经确定了。成员函数调用时隐含传递了this指针,并不是说明成员函数的地址是在运行时生成,而是说明类成员函数实际的原型与直观看上去的并不一样。例:LRESULT Cxxx::proc1(LPVOID)pv; 
    如果是一般的成员函数,则等价于 LRESULT proc1(Cxxx *pThis, LPVOID pv); 函数真正的参数个数是二个。
    而静态成员函数则仍为LRESULT proc1(LPVOID pv); 与全局函数没有区别,相当于只是多了个命名空间(namespace)
      

  4.   

    至于成员函数调用时隐含传递了this指针,刚好证明成员函数的地址是在运行时生成的,=========
    笑死,,,,,,,,,
      

  5.   

    to chehw(chehw)
    既然这样,成员函数也可以作为线程函数,只要把成员函数的地址强行改成LRESULT proc1(LPVOID pv); 的样子不就行了?
      

  6.   

    如果不指定为静态成员函数,无法强行改成那种形式。
    c++编译器在编译时会自动修改成LRESULT proc1(Cxxx *, LPVOID)的形式。
      

  7.   

    to chehw(chehw)
    如果我把成员函数的地址当成一个32位的整数来看待(实际上就是个整数),那么再将这个整数转换成LRESULT proc1(LPVOID pv)样子的指针,也不行吗?
      

  8.   

    记得这两种函数指针的长度都不一样,一般函数指针为4个字节。
    而成员函数隐含this指针后,长度由编译器决定的。
    直接转换的结果是信息丢失,不能保证调用正确。
    如果坚持使用,那么就是一个未定义的行为。下面是网上搜来的。
    成员函数指针——为什么那么复杂?
    类的成员函数和标准的C函数有一些不同。与被显式声明的参数相似,类的成员函数有一个隐藏的参数this,它指向一个类的实例。根据不同的编译器,this或者被看作内部的一个正常的参数,或者会被特别对待(比如,在VC++中,this一般通过ECX寄存器来传递,而普通的成员函数的参数被直接压在堆栈中)。this作为参数和其他普通的参数有着本质的不同,即使一个成员函数受一个普通函数的支配,在标准C++中也没有理由使这个成员函数和其他的普通函数(ordinary function)的行为相同,因为没有thiscall关键字来保证它使用像普通参数一样正常的调用规则。成员函数是一回事,普通函数是另外一回事(Member functions are from Mars, ordinary functions are from Venus)。
    你可能会猜测,一个成员函数指针和一个普通函数指针一样,只是一个代码指针。然而这种猜测也许是错误的。在大多数编译器中,一个成员函数指针要比一个普通的函数指针要大许多。更奇怪的是,在Visual C++中,一个成员函数指针可以是4、8、12甚至16个字节长,这取决于它所相关的类的性质,同时也取决于编译器使用了怎样的编译设置!成员函数指针比你想象中的要复杂得多,但也不总是这样。
    http://study.pay500.com/2/s29208.htm,这里这篇文章。
      

  9.   

    如果我把成员函数的地址当成一个32位的整数来看待(实际上就是个整数),那么再将这个整数转换成LRESULT proc1(LPVOID pv)样子的指针,也不行吗?to yang79tao()  
    其实 chehw(chehw) 说的很对,我没有太多补充。系统启动线程时,根据约定,也即线程函数指针的定我,总是传入一个参数给这个函数。如果你这样强行转换,你给定的函数指针指向的函数,实际是有两个参数,这样,压入两个参数,弹出一个参数,会发生什么?
    其实,创建线程的时候,仅需要一个 函数指针, 这个指针指向任何地址空间都可以,在编译期间都是可以通过的。
      

  10.   

    通过使用thunk技术,类的成员函数也可以做回调函数,比如线程函数、窗口过程函数