当线程函数为C++类成员函数时
2015-12-26 20:03
1076 查看
很多时候我们在C++多线程开发时,都会或多或少遇到线程函数为C++类中的某个成员函数,此时可能会发生什么呢?你有可能会杂么做呢?
接下来我就为大家总结一下我在这方面走过的一个历程
如上述代码,当我编译时会产生如下编译结果
根据第一个error报错,貌似程序希望我们把print函数设为静态函数,第二个error则意思是我们传递的参数不能和std::thread所匹配。我的前几篇博文有写过std::thread相关的知识,它的第一个参数为函数指针,而我们的标准C++里这样是获取不到其成员函数的指针的所以才会产生上述的报错。关于C++获取其成员函数方面的知识,请参考这个链接http://www.zhihu.com/question/27738023
具体如下
这个代码解决了我在一中遇到的问题
在上述代码中,当我的线程函数在使用类的成员函数时,编译时会报错
这是因为,我们的静态成员函数并不能使用非静态的成员变量(因为它没有某个具体对象的this指针)
具体如下
哈哈,当然是有的具体方案如下
我们可以像上述代码那样只需用C++11新标准的std::bind函数将其成员函数与对应的对象指针(即this指针)绑定之后便可高枕无忧的解决我们上述的所有问题了
接下来我就为大家总结一下我在这方面走过的一个历程
1.问题一
记得我在之前在写一个udp传输文件的程序时,我就第一次遇到了线程函数为C++类的成员函数,当时遇到的问题,大概意思如下:#include<iostream> #include <thread> #include <unistd.h> class Test { public: Test():testThread_(print) { } void print(void) { std::cout<<"hello"<<std::endl; } private: std::thread testThread_; }; int main(int argc,char **argv) { Test test; sleep(1000); return 0; }
如上述代码,当我编译时会产生如下编译结果
根据第一个error报错,貌似程序希望我们把print函数设为静态函数,第二个error则意思是我们传递的参数不能和std::thread所匹配。我的前几篇博文有写过std::thread相关的知识,它的第一个参数为函数指针,而我们的标准C++里这样是获取不到其成员函数的指针的所以才会产生上述的报错。关于C++获取其成员函数方面的知识,请参考这个链接http://www.zhihu.com/question/27738023
2.(一)解决方案
根据一种的报错,我想我们想到的最简单的方法就是把成员函数设成静态成员函数具体如下
#include<iostream> #include <thread> #include <unistd.h> class Test { public: Test():testThread_(print) { } static void print(void) { std::cout<<"hello"<<std::endl; } private: std::thread testThread_; }; int main(int argc,char **argv) { Test test; sleep(1000); return 0; }
这个代码解决了我在一中遇到的问题
3.问题二
2中似乎表面上解决了我的问题,但事实上由于2的解决方案,我又遇到了新的问题#include<iostream> #include <thread> #include <unistd.h> class Test { public: Test(int m):n(m),testThread_(print) { } static void print(void) { std::cout<<n<<std::endl; } private: int n; std::thread testThread_; }; int main(int argc,char **argv) { Test test(8); sleep(1000); return 0; }
在上述代码中,当我的线程函数在使用类的成员函数时,编译时会报错
这是因为,我们的静态成员函数并不能使用非静态的成员变量(因为它没有某个具体对象的this指针)
4.(二)解决方案1
解决方案很简单,我们只需给静态成员函数传递某对象的this指针即可具体如下
#include<iostream> #include <thread> #include <unistd.h> class Test { public: Test(int m):n(m),testThread_(print,this) { } static void print(Test *pt) { std::cout<<pt->n<<std::endl; } private: int n; std::thread testThread_; }; int main(int argc,char **argv) { Test test(8); sleep(1000); return 0; }
5.(二)解决方案2
4中的确完全解决了我们在线程中调用类的成员函数的所有问题,但是你会不会感觉其用起来很别扭,本来我们只是向使一个成员函数为线程函数,这样我们就可以在该线程函数中直接使用该类的成员变量了,但是由于2中有叙述的那些原因,结果使我们不得不使用将成员函数设为静态的,结果就是我们现在使用类的成员变量会这么麻烦,感觉好不爽。难道就没什么方法可以让我们不是成员函数变为静态的?哈哈,当然是有的具体方案如下
#include<iostream> #include <thread> #include <unistd.h> #include <functional> class Test { public: Test(int m):n(m),testThread_(std::bind(&Test::print,this)) { } void print(void) { std::cout<<n<<std::endl; } private: int n; std::thread testThread_; }; int main(int argc,char **argv) { Test test(8); sleep(1000); return 0; }
我们可以像上述代码那样只需用C++11新标准的std::bind函数将其成员函数与对应的对象指针(即this指针)绑定之后便可高枕无忧的解决我们上述的所有问题了
相关文章推荐
- 稳定排序和不稳定排序
- 字符串操作(C++程序设计第7周)
- 整数的输出格式(C++程序设计第7周)
- 实数的输出格式(C++程序设计第7周)
- 位操作在java和C/C++中的区别
- C代码中如何调用C++ C++中如何调用C
- 实战c++中的智能指针unique_ptr系列-- 使用unique_ptr来避免if多层嵌套
- 实战c++中的智能指针unique_ptr系列-- 使用unique_ptr来避免if多层嵌套
- extern "c"作用
- 如何用C语言封装 C++的类,在 C里面使用
- C语言学习笔记---伊能C语言学习笔记----寄存器变量
- C++11 并发指南一(C++11 多线程初探)
- C++11 并发指南三(std::mutex 详解)
- C++11 并发指南四(<future> 详解一 std::promise 介绍)
- C++11 并发指南二(std::thread 详解)
- 黑马程序员——C语言---函数
- Codeforces Round #336 (Div. 2) B. Hamming Distance Sum
- C++学习:类成员的访问范围
- c++中vector的用法详解
- C++学习:初识类