虽然标题是这么写的不过还是倒过来先从线程说起吧,Windows via C/C++里提到的线程函数实现这里就不说了,只说创建需要给的一个函数指针。
后来多次尝试+Google后发现无论怎样都不可以把后一种函数指针赋给前一个类型的参数,除非你另写一个C函数包一下(如下),就算我自己做了成员函数访问成员变量的互斥操作都不行!
另外,由于这样写起来很麻烦,也可以用typedef:
uintptr_t _beginthreadex(
void *security, // security properties, pass NULL for most times
unsigned stack_size, // pass 0 to use a default thread stack size
unsigned ( *start_address )( void * ), // pointer to a function where thread starts
void *arglist, // the function may needs parameters
unsigned initflag, // pass NULL to start the thread right after the _beginthreadex function
unsigned *thrdaddr // pointer to an unsigned integer for holding the thread ID
);
Windows下创建线程使用CreateThread的API,Windows的C Runtime里提供了如上的函数。由于CRT里有一些全局变量如errno,所以如果在线程中使用了C函数,那可能会发生多线程访问该全局变量的问题(当然C标准库里大多数函数都是线程安全的),所以该书作者表示尽可能地别用CreateThread,都用_beginthreadex(在<process.h>中),反正它们的参数完全一样,就是类型不同需要强制转换。
扯远了,问题1:需要关注的就是那个start_address变量,是一个指向unsigned (*)(void*)函数的指针。对一个类A而言,它的成员函数指针则是unsigned (A::*)(void*)的。
class A {
unsigned Foo(void*) { return 0; }
};
typedef unsigned (*FUNC1)(void*);
typedef unsigned (A::*FUNC2)(void*);
后来多次尝试+Google后发现无论怎样都不可以把后一种函数指针赋给前一个类型的参数,除非你另写一个C函数包一下(如下),就算我自己做了成员函数访问成员变量的互斥操作都不行!
A obj;
unsigned FUNC_WRAPPER(void* p) {
obj.Foo(p);
}
也就是说多线程必须使用全局函数了。
问题2:成员函数的指针的用法。
在知道类成员函数指针不能赋值给全局函数指针之后,想合法地尝试一下:
class A {
public:
unsigned Foo(void*) { return 0; }
void Test(unsigned (A::*pFoo)(void*), void* p) {
pFoo(p); // Compiler Error
}
};
int main() {
A a;
a.Test(A::Foo); // Error
a.Test(&A::Foo); // OK
return 0;
}
上述main函数中的错误行,要获得一个成员函数指针,需要用&A::Foo才行,不可以用A::Foo,VS也会提示你更改为正确的方式。
而A::Test()函数中的错误就有点麻烦了,需要更正为:
class A {
public:
unsigned Foo(void*) { return 0; }
void Test(unsigned (A::*pFoo)(void*), void* p) {
(this->* pFoo)(p); // inside the class itself, use "this" pointer
}
};
void GlobalTest(unsigned (A::*pFoo)(void*), void* p) {
A a;
(a.* pFoo)(p); // in a global function, use class instance
}
另外,由于这样写起来很麻烦,也可以用typedef:
class A {
public:
typedef unsigned (A::*FUNC_PTR)(void*);
unsigned Foo(void*) { return 0; }
void Test(FUNC_PTR pFoo, void* p) {
(this->* pFoo)(p); // inside the class itself, use "this" pointer
}
};
void GlobalTest(A::FUNC_PTR pFoo, void* p) {
A a;
(a.* pFoo)(p); // in a global function, use class instance
}
跪求大大解释一下上面成员函数指针的运行机理orz