Effective C++第七章模板與泛型編程 條款41-條款48

條款41.瞭解隱式接口與編譯期多態

面向對象的三大特性之一多態是指的運行期多態,在程序運行期間確定對象調用哪一個虛函數。
編譯期多態是對於模板參數而言,通過模板具現化和函數重載解析實現,以不同的模板參數具現化導致調用不同的函數。
像我們在類中定義的成員函數都是顯示接口,而對於模板參數而言,接口是隱式的,以有效的表達式爲基礎。
總結:

  • 類和模板都支持接口和多態
  • 對於類而言接口是顯示的,以函數簽名(函數名稱、參數類型、返回類型)爲中心,多態是通過虛函數實現發生於運行期
  • 對於模板參數而言,接口是隱式的,以有效表達式爲基礎,通過對模板的具現化和函數重載解析實現發生於編譯期

條款42.瞭解typename 的雙重意義

總結:

  • 聲明template參數時,前綴關鍵字class和typename可互換
  • 請使用關鍵字typename標識嵌套從屬類型名稱;但不得在基類列或成員初值列內以它作爲base class修飾符

條款43.學習處理模板化基類內的名稱

當模板像類一樣發生派生類對基類的繼承時,並不能像類的繼承一樣,派生類完全繼承基類中的函數,因爲這裏涉及到模板參數的具現化,如下例子,編譯器爲了防止某種類型的基類中沒有相應函數的定義,在下面調用基類的函數的過程中,出現編譯不通過。

這裏是引用
在這裏插入圖片描述

那麼對於這種問題如何解決呢?如何通過編譯呢?
在派生類中通過“this->”指涉基類模板內的成員的名稱或者明白寫出基類的資格修飾符

方法一:這裏是引用
方法二:
在這裏插入圖片描述
方法三:
在這裏插入圖片描述


條款44.將與參數無關的代碼抽離templates

總結:

  • 模板生成多個類和函數,所以任何模板代碼都不該與某個造成膨脹的模板參數產生相依關係
  • 因非類型模板參數而造成的模板參數往往可以消除,做法是以函數參數或者類成員 變量替換模板參數
  • 因類型參數而造成的代碼膨脹,往往可以降低,做法是讓帶有完全相同二進制表述的侷限類型共享實現碼

條款45.運用成員函數模板接受所有兼容類型

使用具有繼承關係的兩個類:基類型和派生類型具現化模板,產生的具現體並不具有類似於基類和派生類的繼承關係.

泛化的拷貝構造函數:
這裏是引用
上述泛化的拷貝構造函數存在着一定的問題,例如T是派生類型,U是基類類型,我們不希望根據基類類型的指針創建派生類類型的指針,我們想要的是根據派生類類型的指針創建基類類型的指針。
於是有如下的改造方式:在這裏插入圖片描述
只要在copy構造函數中,初始化的參數列表能夠初始化成功,就能夠達到上述目標,顯然基類的指針不能拷貝給派生類的指針


成員函數模板:這裏是引用
在這裏插入圖片描述
說明:成員函數模板並不會改變語言規則,也就是說:創建一個類時會默認包含默認構造函數、copy構造函數、賦值函數、析構函數,並不會由於泛化的拷貝構造函數的存在而影響copy構造函數
在這裏插入圖片描述

總結:

  • 使用成員函數模板生成可接受所有兼容類型的函數
  • 如果聲明成員函數模板用於泛化拷貝構造或者泛化賦值函數,依然需要聲明正常的拷貝構造函數和賦值函數。

條款46.需要類型轉換時請爲模板定義非成員函數

類似於條款24.需要類型轉換時,爲此採用非成員函數。
總結:
當我們寫一個函數模板,而它所提供的與該模板相關的函數支持所有參數的隱式類型轉換時,需要將那些函數定義成模板類內部的友元函數。
解釋:
如果使用函數模板,會涉及到實參類型的推導過程,實參類型的推導過程不會將通過構造函數的調用實現隱式的類型轉化納入考慮。
爲了實現類型的轉換,可以將函數定義成友元函數,以至於在類的具現化時就能夠確定函數中形參的類型。那麼此時原來的函數模板不在是函數模板而是類模板中的成員函數,因爲在具現化類的時候成員函數就已經確定了。
這時,在調用該函數的時候,就可以使用隱式轉換。
雖然使用了友元函數,但與傳統的友元函數的用途毫無關係

  • 爲了讓類型轉換可能發生於所有實參的身上,我們需要非成員函數(條款24)
  • 爲了讓這個函數自動具現化,需要將他聲明在類內部
  • 聲明在類內部唯一的辦法就是讓她成爲友元

條款47.請使用traits classes表現類型信息

traits並不是關鍵字,它是一種技術,這種技術的要求之一是:對內置類型和用戶自定義類型表現的一樣好。
習慣上,trait總是被實現爲structs,但往往被稱爲traits class
總結:

  • traits classes使得類型相關信息在編譯期可用,他們以模板和模板特化實現
  • 整合重載技術後,traits class有可能在編譯期對類型執行if…else測試

對於下述函數,需要在編譯期確定iter的類型
這裏是引用


條款48.認識template元編程

總結:

  • TMP(Template metaprogramming)模板元編程可將工作由運行期移往編譯期,因而可以實現早期錯誤檢測和更高的執行效率
  • TMP可用來生成基於政策選擇組合的客戶定製代碼,也可用來避免生成對某些特殊類型並不適合的代碼
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章