modern c design 第十一章

2021-04-12 17:39:21 字數 2688 閱讀 8078

本章介紹了經常遇到的雙分派的一種泛型解決方案。 c++在語法上實現了單分派, 即虛函式, 通過動態機制選擇相應的函式。 雙分派是形如fun(object1* a, object2* b). 根據a和b的實際型別動態自動分派乙個處理函式。

最容易想到的方案,蠻幹法: 寫一大堆過載函式. 不過這種方法會有很強的依賴性。 也提供了一種泛化蠻幹法的實現: executor是實現了各種具體實現的類, 其中實現了各種fire函式. baselhs是左運算元的基類, typeslhs是乙個typelist, 包括了左運算元可能的型別集合. baserhs和typesrhs類似,不過針對右運算元. symmetric是是否對稱, 如果對稱, 則需要實現的函式減半. resulttype是返回值型別,通常為void.

template

<

class executor,

class baselhs,

class typeslhs,

bool symmetric = true,

class baserhs = baselhs,

class typesrhs = typeslhs,

typename resulttype = void

>

class staticdispatcher

template

static resulttype dispatchrhs(somelhs& lhs, baserhs& rhs,

executor exec, typelist)

return dispatchrhs(lhs, rhs, exec, tail());

}static resulttype dispatchlhs(baselhs& lhs, baserhs& rhs,

executor exec, nulltype)

template

static resulttype dispatchlhs(baselhs& lhs, baserhs& rhs,

executor exec, typelist)

return dispatchlhs(lhs, rhs, exec, tail());

}public:

static resulttype go(baselhs& lhs, baserhs& rhs,

executor exec)

};實現方式還是模板元程式設計的方法, 利用靜態遞迴實現. 如果對第三章內容有相當的理解,讀懂這段也非常簡單了.

symmetric是使用bool的模板變數的分派實現的.  利用了乙個輔助類invocationtraits. 從輔助類的使用可以看到, 不同的職責都分派給了不同的類去實現, 耦合性非常低,利於重用.

template

struct invocationtraits

static resulttype

dodispatch(somelhs& lhs, somerhs& rhs,

executor& exec, int2type)

};由於暴力法的依存性以及查詢效能, 只有在類很少時使用.  必須考慮其他的實現

對數型分派.  依賴type_info的before函式進行排序, 維護乙個執行期map, 為不同的組合註冊callback, 根據2分查詢尋找適合的callback, 可以實現對數效能. 即o(lgn).  此實現考慮到轉型的問題, 函式呼叫進行了一次包裝. 這一段讀的不是很明白.  目的是得到具體型別不丟失, 需要實際使用才能更好理解吧. 利用前面提供的functor可以分派到泛函式. 實現:

template

<

class baselhs,

class baserhs = baselhs,

typename resulttype = void,

typename callbacktype = resulttype (*)(baselhs&, baserhs&)

>

class basicdispatcher

template

bool remove()

resulttype go(baselhs& lhs, baserhs& rhs);

};// non-inline to reduce compile time overhead...

template

void basicdispatcher

::doadd(typeinfo lhs, typeinfo rhs, callbacktype fun)

template

bool basicdispatcher

::doremove(typeinfo lhs, typeinfo rhs)

template

resulttype basicdispatcher

::go(baselhs& lhs, baserhs& rhs)

return (i->second)(lhs, rhs);

}由於多繼承的問題, static轉型在菱形繼承的時候不能使用, 而dynamic的轉型效能消耗較大. 所以loki提供了乙個轉型策略.

最後, 還有乙個basicfastdispatcher. 是常數期的分派方法.  實際是使用了陣列方法解決的問題, 代價是每個類都需要包括乙個巨集, 這個巨集定義了那個類在陣列中的下標.

對我來說, 了解了這些概念足以,  暫時的應用中,對數法或者暴力法可能更為實用一些. 高階內容留待需求的提公升吧. 不過對於思想的提公升, 這些概念是意義重大的.

Modern C Design 繁體版勘誤1

p34 template class niftycontainer 這段 在編譯時會出現下面警告,並且valuetype缺少型別說明符錯誤 warning c4346 select resault 依賴名稱不是型別 正確的寫法是 template class niftycontainer typen...

Android 二 第十單元

先導入乙個註解包,就可以避免方法重寫時的注釋報錯的問題。contentprovider是四大元件之一,可以使不同的應用程式之間實現資料共享的功能。需要自己編寫訊息提供者和接受者2個應用程式,乙個提高內容,乙個接受內容。還需要uri位址,就是提供者的包名,uri前面一定要加conten 是固定寫法不可...

第十周總結

這周一開始說的是要考試,但是最後又說等通知,所以就有時間複習了,要是真的這周考試那就涼涼了。之前學的有的忘了,有的是根本都不會,反正都得從頭開始看。這周講課的時候我看了看講課表,嗯,下下個星期就到我了。下個星期又要考試,所以說還是考試重要,講課先放到一邊,等考試過了再說,畢竟考的那兩門都挺難的。不過...