Curiously recurring template pattern with ptrhead
因此,我想知道您是否可以使用奇怪的重复模板模式来绕过pthread使用类方法的局限性,甚至通过执行类似的操作来创建类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | template <class T> class thread_helper { static void* create(void *input) { T * output=new T; return static_cast<void*>(output); } static void* using(void *input) { T::use(input); } }; class user : public thread_helper<user> { void method(int x) { //does something } static void use(void* input) { this->method(static_cast<int>(input)); } }; |
然后可以使用pthread调用类创建
1 | pthread_create(thread_variable, NULL, thread_helper::create<some_class>, void); |
另一个电话呢
1 | pthread_create(thread_variable, NULL, user::using(), void); |
注意:上面的代码中有很多错误。请不要为他们把我撕成碎片。我只是想画一幅我想做的事情。我还想知道是否有更好的方法来做这个手术。
另外,第二个
我要发布一个有效的测试代码。它涉及到大量的锅炉板代码。它真的很难看,但很管用。注意:稍后我可能会更改thread_helper的create方法,这样它就不能用于线程。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | #include <iostream> #include"pthread.h" using namespace std; template <class I> struct helper { void *(I::*method)(void *); //enables you to call and get information from any non static class method I *ptr; //this is the class pointer used to call the member pointer void *info; //this is what you pass into the member pointer }; template <class T> class thread_helper { public: static void *create(void *in) { T * output=new T; return static_cast<void*>(output); } static void *method(void *in) { helper<T> *utilize = static_cast<helper<T> *>(in); return (utilize->ptr->*utilize->method)(utilize->info); } }; class test: public thread_helper<test> { public: void *test_method(void *in) { int *val = (int *)in;//note: not static_casting since this is not a class *val *= 4; return val; //auto casts to void * } }; int main() { //initialize test test * second = static_cast<test*>(test::create(NULL)); //initialize helper helper<test> first; first.ptr = second; first.method = &test::test_method; int val = 4; first.info = &val;// //setup threads pthread_t thread; void *ans; //call test_method and retrieve answer pthread_create(&thread, NULL, test::method, static_cast<void *>(&first)); pthread_join(thread, &ans); cout <<"the answer is"<< *(int *)ans <<endl; return 0; } |
如前所述,如果您使用pthreads,此解决方案可以工作。它是编写函数或静态方法来调用类方法的通用替换。
如果使用Boost或C++ 11线程,则不需要这种方法,可能不应该使用它,因为它需要大量的锅炉板代码(指针铸造)。