最近在看陳碩的MUDUO網絡通訊庫的過程當中,發現做者大量使用了Boost::function以及Boost::bind功能,爲了可以正常的學習做者的代碼,決定先弄明白function以及bind的功能。ios
Boost::Function 是對函數指針的對象化封裝,在概念上與廣義上的回調函數相似。相對於函數指針,function除了使用自由函數,還可使用函數對象,甚至是類的成員函數,這個就很強大了哈。windows
#include <boost/function.hpp> #include <boost/bind.hpp> #include <iostream> using namespace std; class TestA { public: void method() { cout<<"TestA: method: no arguments"<<endl; } void method(int a, int b) { cout<<"TestA: method: with arguments" <<"value of a is:"<<a <<"value of b is "<<b <<endl; } }; void sum(int a, int b) { int sum = a + b; cout<<"sum: "<<sum<<endl; } int main() { boost::function<void()> f; TestA test; f = boost::bind(&TestA::method, &test); f(); f = boost::bind(&TestA::method, &test, 1, 2); f(); f = boost::bind(&sum, 1, 2); f(); }
輸出結果:
Administrator@8bd5ec9e02074bf ~/source $ ./BoostFunction.exe TestA: method: no arguments TestA: method: with argumentsvalue of a is:1value of b is 2 sum: 3
在實現自定義的線程類時,曾經這麼幹過:定義虛函數run(),用戶自定義的CustomThread::Thread後,本身實現run()函數就OK了。 當時以爲這麼作也不錯。
如今有了boost::function/boost::bind咱們能夠這麼幹:
定義一個線程類:
.h文件網絡
#include <pthread.h> #include <string> #include <boost/function.hpp> #include <boost/bind.hpp> using namespace std; class Thread { typedef boost::function<void()> ThreadFun; public: Thread(const ThreadFun& threadFun,const string& threadName = string()); pid_t getThreadId(); string getThreadName(); int start(); private: static void* startThread(void* thread); private: pthread_t m_thread; //線程句柄 pid_t m_tid; //線程ID string m_strThreadName; //線程名稱 bool m_bStarted; //線程是否啓動 ThreadFun m_func; //線程處理函數 };
.cpp文件函數
#include "thread.h" Thread::Thread(const Thread::ThreadFun& threadFun, const string& threadName): m_func(threadFun), m_strThreadName(threadName) { } int Thread::start() { m_tid = pthread_create(&m_thread, NULL, &startThread, this); return 0; } void* Thread::startThread(void* obj) { Thread* thread = static_cast<Thread*>(obj); thread->m_func(); return NULL; } pid_t Thread::getThreadId() { return m_tid; }; string Thread::getThreadName() { return m_strThreadName; }
測試程序學習
void ThreadProcess() { int count = 100; for (int i = 0; i < count; i++) { if (i % 10 == 0) cout<<"\n"; cout<<i<<"\t"; } } int main() { boost::function<void()> f; f = boost::bind(&ThreadProcess); Thread thread(f, "ThreadTest"); thread.start(); sleep(1000*1000); return 0; }
輸出結果(Cygwin):
>根據上述程序,咱們能夠發現,這樣咱們就不須要定義不少不少的類去繼承Thread類,而只須要寫好線程運行函數,set到Thread類中便可。不過也不能說利用虛函數留接口給用戶實現就很差,只不過如今多了一種方法。(陳碩很反對用虛函數做爲結構提供給用戶去作實現,可是我如今尚未切身的體會以爲那裏很差)
本身之前在windows下實現的基於虛函數的線程類實現:http://my.oschina.net/myspaceNUAA/blog/41014測試
2. boost::function/bind還有不少其餘高級用法,我這邊只是用來當作一個函數指針用了哈this