前面在做 http server 的時候,需要做乙個**的介面,要求能夠繫結類的函式以及普通的函式到這個**裡,對於這種應用要求,選擇 boost 的 bind 和 function 是最合適不過了,但現在情況有些不同,我不準備在現在做的這個東西裡加入 boost, 本著以造輪子為樂的精神,現在只能捋起袖子自己來搞乙個。
使用的時候一直沒有太留意它們的實現,現在要做起來,發現也不是想像中那麼輕而易舉。這個東西做到最後要實現的效果就是設計乙個泛型的 function holder,這個 holder 既能包裝類的函式,又要能包裝一般的函式,換言之就是能像下面一樣來使用。
#include usingnamespace
std;
class
cs};
int proc(double
d)int
main()
簡單實現
一開始你可能會想,a piece of cake! 直接封裝乙個 function 就行了。
templateclass function1: public
copyable
ret_type
operator() (arg_type arg)
private
: norm_proc fun_;
};
好,這個類可以封裝一般的函式了,那類的函式呢?one more!
templateclass function2: public
copyable
ret_type
operator() (arg_type arg)
private
: cs* obj_;
mem_proc proc_;
};
很快我們就發現有問題了,function1 和 function2 是兩不同的模板類,bind() 的時候沒法處理:bind() 返回的應該要是乙個統一的型別。
怎麼辦呢?我們可能想到要抽取出乙個基類來,思路是對的!但還有些細節要處理。
比如:bind() 返回的是什麼型別呢?function1,function2 的基類嗎?這好像做不到,不能直接返回 object,所以下面的做法是錯的。
templateclass function_base: public
copyable
virtual ret_type
operator() (arg_type arg) = 0;};
template
class function2: public
function_base
ret_type
operator() (arg_type arg)
private
: cs* obj_;
mem_proc proc_;
};template
function_base
bind(ret_type (cs::* proc)(arg_type), cs*pc)
那直接返回指標不就完了!
返回指標可行,但不好用,而且容易記憶體洩漏。解決的辦法是對返回的指標再包一層,嗯,raii。但
等等,好像如果再包一層,就已經能直接隔開底下的 function holder 與具體的呼叫了啊!perfect!
templateclass function_base: public
copyable
virtual ret_type
operator() (arg_type arg) = 0;};
template
class function1: public
function_base
ret_type
operator() (arg_type arg)
private
:norm_proc fun_; };
template
class function2: public
function_base
ret_type
operator() (arg_type arg)
private
: cs* obj_;
mem_proc proc_;
};template
class functioin: public copyable
ret_type
operator()(
arg_type
arg)
private:
function_base* obj_;
};template
function
bind(ret_type (cs::* proc)(arg_type), cs*pc)
經過這樣一包裝,function 類好像已經能夠用來 bind 類的成員函式了, 也沒那麼難嘛!
但是,**很差勁:
1) 沒有處理記憶體釋放。
2) 沒有處理 copy costructor,assignment operator()。
3) 普通函式還是不能直接賦值給 function 類。
再改一下 function 類:
templateclass
function
function(norm_proc proc = 0): fun_(new function1(proc)), ref_(new
int(1
)) {}
ret_type
operator() (arg_type arg)
~function()
void
release()
}function(
const function&fun)
void
operator=(const function&fun)
private
:
int*ref_;
function_base
*fun_;
};
這樣一來,終於能夠正常使用了,
可以看到,為了使得 function 類能被 copy/assign,這裡面使用引用計數來控制記憶體的釋放問題,上面的實現比較簡單,也不是執行緒安全的,只是滿足了基本的使用需求,具體的**參看這裡。
**寫得較快,暫且就這樣了,不知道 boost 是怎樣實現的?得找個時間研究研究。
boost bind使用指南
bind boost 標頭檔案 boost bind.hpp bind 是一組過載的函式模板.用來向乙個函式 或函式物件 繫結某些引數.bind的返回值是乙個函式物件.它的原始檔太長了.看不下去.這裡只記下它的用法 9.1 對於普通函式 假如有函式 fun 如下 void fun int x,int...
boost bind使用指南
bind boost 標頭檔案 boost bind.hpp bind是一組過載的函式模板.用來向乙個函式 或函式物件 繫結 某些引數.bind的返回值是乙個函式物件.它的原始檔太長了.看不下去.這裡只記下它的用法 9.1 對於普通函式 假如有函式 fun 如下 void fun int x,int...
boost bind使用指南
bind boost 標頭檔案 boost bind.hpp bind 是一組過載的函式模板.用來向乙個函式 或函式物件 繫結某些引數.bind的返回值是乙個函式物件.它的原始檔太長了.看不下去.這裡只記下它的用法 9.1 對於普通函式 假如有函式 fun 如下 void fun int x,int...