多型主要是通過繼承和虛函式來實現的,這兩個機制都是在執行期進行處理的,因此把這種多型稱為動多型。平常所談論的c++多型指的就是這種動多型。
模板也允許使用單一的泛型標記來關聯不同的特定行為,這種借助於模板的關聯是在編譯器進行處理的,因此把這種多型稱為靜多型。
動多型:
動多型的設計思想主要在於:對於幾個相關物件的型別,確定它們之間的乙個共同功能集,然後在基類中,把這些共同的功能宣告為多個虛函式介面。
基於這種設計方案的乙個典型例子是:乙個用於管理某些幾何形狀,並且能夠以某種方式對這些形狀進行修改的應用程式。
對於動多型而言,最引人注目的特性或許是處理異類容器的能力。
// 畫出屬於異類集合的geoobjs物件
void drawelems (std::vectorconst& elems)
}int main()
靜多型:
可以把動多型中的mydraw()函式:
void mydraw (geoobj const& obj)//geoobj是乙個抽象基類
改寫為:
template
void mydraw (geoobj const& obj) //geoobj是模板引數
使用動多型,在執行期只具有乙個mydraw()函式
使用模板,則可能具有多個不同的函式,如mydraw()和mydraw()。
不過,靜多型不允許異類集合的處理,因為所有的型別都必須能夠在編譯器確定。
動多型和靜多型:
通過繼承實現的多型是繫結的和動態的:
繫結的含義是:對於參與多型行為的型別,它們的介面是在公共基類的設計中就預先確定的
動態的含義是:介面的繫結是在執行期完成的
通過模板實現的多型是非繫結的和靜態的:
非繫結的含義是:對於參與多型行為的型別,它們的介面是沒有預先確定的
靜態的含義是:介面的繫結在編譯器完成的
各自的優點:
動多型:
能夠優雅地處理異類集合
可執行**的大小通常比較小(因為只需要乙個多態函式,但對於靜多型而言,為了處理不同的型別,必須生成多個不同的模板例項)
可以對**進行完全編譯;因此並不需要發布實現原始碼(但是,分發模板庫通常都需要同時分發模板實現的源**)
靜多型:
可以很容易地實現內建型別的集合
所生成的**效率通常比較高(因為並不存在通過指標的間接呼叫,而且,可以進行演繹的非虛函式具有更多的內聯機會)
對於只提供部分介面的具體型別,如果在應用程式中只是使用到這一部分介面,那麼也可以使用該具體型別,而不必在乎該型別是否提供其他部分的介面
C Templates 模板中的名稱
名稱的分類 識別符號 運算子id 型別轉換函式id 模板id 非受限id 受限id 受限名稱 非受限名稱 依賴性名稱 非依賴性名稱 如果乙個名稱使用域解析運算子或者成員訪問運算子來顯式表明它所屬的作用域,就稱該名稱為受限名稱。如果乙個名稱依賴於模板引數,就稱為依賴性名稱。名稱查詢 受限名稱的名稱查詢...
C Templates 模板實戰
包含模型 把模板的定義包含在宣告模板的標頭檔案裡面,即讓定義和宣告都位於同乙個標頭檔案中。如果不需要考慮建立期的時間問題,建議盡量使用包含模型來組織模板 非內聯函式模板在呼叫的位置並不會被擴充套件,而是當它們基於某種型別進行例項化之後,才產生乙份新的 基於該型別的 函式拷貝。顯式例項化 顯式例項化指...
C Templates 深入模板基礎
引數化宣告 存在3種模板引數 1.型別引數 2.非型別引數 3.模板的模板引數 非型別引數 非型別引數表示的是 在編譯期或鏈結期可以確定的常值,這些引數的型別必須是下面的一種 非型別模板引數的宣告和變數的宣告很相似,但它們不能具有static mutable等修飾符 只能具有const和volati...