函式物件點滴

2021-03-31 14:28:01 字數 2073 閱讀 7808

hanlray@gmail.***

函式物件是就是乙個類物件,由於過載了呼叫運算子()而具有了類似函式的呼叫形式。通常使用函式物件來實現某種形式的**, 和傳統的用函式指標實現的**相比,函式物件有以下優點:

理由是stl中可以使用函式物件的演算法都被設計為值傳遞。當然你可以使用顯式模板實參來傳引用,但是那樣可能會帶來問題 (比如物件切割問題);精心設計的類或函式模板或許可以去掉這些問題,但是你能保證在這些模板裡不使用stl嗎?

如果按值傳遞,那麼函式物件就不能是多型的,並且應該很小。而在現實中函式物件又往往不是這樣,這時候我們就需要使用c++ 的慣用法pimpl:把大和/或多型的函式物件的資料和/或多型移到另乙個類(實現類)中,然後給你的函式物件乙個指向這個新類的指標, 這樣就需要多個函式物件例項共享乙個實現類例項,boost的shared_ptr是當然之選:

template

class bpfcimpl : public unary_function;

template

class bpfc : public unary_function

...};

有時候我們需要實現乙個一般化的**,可以**普通函式或函式物件,只要它們滿足規定的型別(返回值型別,引數個數和型別),當然 可以用模板引數來實現該**,就像stl的演算法作的那樣,但是對使用類的情況,常常需要把該類變成類模板,而類模板必須顯式例項化,這 樣客戶端的**就顯得不夠簡潔,boost.function通過乙個巧妙的包裝,統一了型別一致的普通函式和函式物件,同時又不失去型別安全性, 具有較強的使用價值。boost.thread就使用了boost.function:

class thread

;

這裡thread的建構函式宣告它接受乙個引數個數為0,返回值型別為void的函式型別,不管它是普通函式還是函式物件。 不過boost.function提供的便利性也是有代價的,除占用空間上有增加外,執行效率也有降低,那些效能狂人可要注意了.

有時候我們想要**的函式或函式物件不滿足該**所期望的型別,僅僅是因為多了幾個事先可以確定的引數,這時用boost.bind就很方便, 它是std::bind1st和std::bind2nd的一般化,不僅能支援更多引數,繫結方式也很靈活,而且支援函式物件和成員函式的繫結。比如想使用 boost::thread建立乙個執行緒來執行函式:void f(int i),如果這樣寫:boost::thread thrd(f)是不對的,因為thread建構函式宣告接受 的是乙個沒有引數且返回型別為void的型別,而且不提供引數i的值f也無法執行,這時就可以寫:

boost::thread thrd(bind(f, 1))//假設以1為實參執行f

有乙個shape物件的容器v,想要對其容納的每個物件呼叫draw方法,寫成

for_each(v.begin(),v.end(),&shape::draw)

是不對的,因為你不能在成員函式和成員函式指標上進行呼叫,必須通過乙個物件或物件指標來呼叫成員函式。通過 boost.mem_fn生成的函式物件以指向成員函式所在類的指標或引用或智慧型指標為第乙個引數,它可以支援多個引數,因此是stl中 mem_fun等的一般化.

有乙個物件指標的容器,當要銷毀其引用的那些物件時,你會怎麼做?手寫迴圈?真麻煩;用for_each似乎省去了寫迴圈的煩惱,可是又 不得不在另外的地方寫乙個函式物件,好像更麻煩,似乎把乙個本該區域性解決的問題擴散到了外部,而且會降低**的可讀性.這時候 boost.lambda也許可以幫上忙:

for_each(v.begin(), v.end(), bind(delete_ptr(), _1))

通過對lambda表示式生成無名的函式物件,lambda能有效地避免手寫簡單函式物件的煩惱.對一般的可以過載的運算子,用法和在c++中一樣, 如<<,=等;對特殊的可以過載的運算子如new,delete等,有其對應的表達方式(如上例);對函式呼叫用lambda提供的bind;甚至連控制結構 都支援。

last modified: sunday, march 6th, 2005

html conversion by

tex2page 2005-02-27

物件導向點滴

1.物件導向最重要的幾個概念 物件,類,介面,封裝,繼承,多型。1.物件 在物件導向程式設計裡面,萬事萬物都被視為物件,物件是對資料和操作的封裝。2.類 對一類物件的抽象。3.介面 一組功能契約。4.封裝 隱藏物件細節。6.多型 物件導向非常好的特性,更是所有模式和構架的基礎。多型允許執行時決定例項...

delphi學習點滴 幾個關閉函式

表示關閉的有如下函式 hide close free release destrory terminate freeandnil halt hide 只是將窗體隱藏。close 對於窗體而言,close與hide的區別是如果窗體內有方法執行,close時候會終止窗體物件所執行的方法 而hide不會,...

Delphi中呼叫API函式經驗點滴(三)

三 防止多次載入應用程式例項 某些應用程式需要禁止使用者載入多次例項。比如,控制面板中的應用程式,不管使用者開啟多少次,同一應用程式只有乙個例項,而且每一次試圖重複開啟都會自動啟用已經存在的例項。windows api 提供了函式findwindow,可以是應用程式在啟動時檢查自己是否已經存在。該函...