這是一篇介紹bind和function用法的文章,原由是近來讀陳碩的文章,提到用bind和function替代繼承,因而就熟悉了下bind和function的用法,都是一些網上都有的知識,記錄一下,期冀對他人也有用處。app
注:本文暫時不探索bind和function的實現和開銷。函數
1. bind 是什麼this
boost::bind 是std::bindlist 和 std::bind2nd的結合體。它提供一個任意的函數對象(仿函數)、函數、函數指針、成員函數指針。 它能夠綁定任意的參數。bind 沒有對函數對象有任何的要求。spa
2. bind 到函數/函數指針指針
void print(int array[], int size) { for (int i = 0; i < size; i++) { printf("%d\n", array[i]); } } int main(int argc, const char *argv[]) { int array[]= {1,2,1,34,5,5,56,9,6,10}; int len = sizeof(array)/sizeof(array[0]); // 綁定普通函數 boost::bind(print, _1,_2)(array, len); // 與function結合 boost::function<void(int [], int)> fn = boost::bind(print, _1,_2); fn(array, len);
return 0; }
注意,_1 和_2 表示佔位符。code
3. bind到類成員函數對象
class Thread {p
public: Thread (int id):thread_id(id) {} virtual void Run() { printf("this is threads %d\n", thread_id); } private: int thread_id; }; class CallWrapper { public: typedef boost::function<void ()> CallBack; CallWrapper (); static void Run(CallBack fn) { printf("%s\t%d\n", __FUNCTION__, __LINE__); fn(); } }; int main() { Thread worker(10); // 綁定類成員函數,worker至關於this指針 boost::bind(&Thread::Run, worker)(); // 做爲參數,參數用function CallWrapper::Run(boost::bind(&Thread::Run, worker)); }
上面是一個比較簡單的市立,下面給出一個比較適用的分行讀取文件的例子 blog
#include <boost/function.hpp> #include <boost/bind.hpp> #include <stdio.h> #include <string> #include <map> class SimpleLineReader { public: SimpleLineReader (const string& filename) { fp_ = fopen(filename.c_str(), "r"); } ~SimpleLineReader (){ if (fp_) { fclose(fp_); } } typedef boost::function<bool (const std::string& line)> Callback; bool ProcessLines(Callback fn) { if (!fp_) { return false; } char *line = NULL; size_t len = 0; ssize_t read; while ((read = getline(&line, &len, fp_)) != -1) { string str(line, read); fn(line); } free(line); return true; } private: FILE* fp_; }; class CityLoader { public: CityLoader (){} int init(const std::string& filename) { SimpleLineReader reader(filename); reader.ProcessLines(boost::bind(&CityLoader::ProcessLine, this, _1)); printf("readline\t%d\n", city_map_.size()); } ~CityLoader () { } private: bool ProcessLine(const std::string& line) { static int cnt = 0; if (line.empty()) { return true; } city_map_.insert(make_pair(++cnt, line)); return true; } std::map<int, std::string> city_map_; }; void test_simple_line_reader() { CityLoader city_loader; city_loader.init("data/city.txt"); } int main() { test_simple_line_reader(); }
這就是所有了。我的認爲比較方便。繼承