boost bind及function的簡單實現

2022-07-06 23:42:17 字數 3306 閱讀 8232

前面在做 http server 的時候,需要做乙個**的介面,要求能夠繫結類的函式以及普通的函式到這個**裡,對於這種應用要求,選擇 boost 的 bind 和 function 是最合適不過了,但現在情況有些不同,我不準備在現在做的這個東西裡加入 boost, 本著以造輪子為樂的精神,現在只能捋起袖子自己來搞乙個。

使用的時候一直沒有太留意它們的實現,現在要做起來,發現也不是想像中那麼輕而易舉。這個東西做到最後要實現的效果就是設計乙個泛型的 function holder,這個 holder 既能包裝類的函式,又要能包裝一般的函式,換言之就是能像下面一樣來使用。

#include using

namespace

std;

class

cs};

int proc(double

d)int

main()

簡單實現

一開始你可能會想,a piece of cake! 直接封裝乙個 function 就行了。

template

class function1: public

copyable

ret_type

operator() (arg_type arg)

private

: norm_proc fun_;

};

好,這個類可以封裝一般的函式了,那類的函式呢?one more!

template

class function2: public

copyable

ret_type

operator() (arg_type arg)

private

: cs* obj_;

mem_proc proc_;

};

很快我們就發現有問題了,function1 和 function2 是兩不同的模板類,bind() 的時候沒法處理:bind() 返回的應該要是乙個統一的型別。

怎麼辦呢?我們可能想到要抽取出乙個基類來,思路是對的!但還有些細節要處理。

比如:bind() 返回的是什麼型別呢?function1,function2 的基類嗎?這好像做不到,不能直接返回 object,所以下面的做法是錯的。

template

class 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!

template

class 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 類:

template

class

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...