Effective C++學習筆記(7)

目錄

  • 條款41:了解隱式接口和編譯多態
  • 條款42:了解typename的雙重意義
  • 條款43:學習處理模板化基類內的名稱
  • 條款44:將與參數無關的代碼抽離templates
  • 條款45:運用成員函數模板接受所有兼容類型
  • 條款46:需要類型轉換時請為模板定義非成員函數
  • 條款47:請使用traits classes表現類型信息
  • 條款48:認識模板元編程

條款41:了解隱式接口和編譯多態

  • 顯示接口:在源碼中可以找到明確可見的函數接口。
    在這里插入圖片描述

- 隱式接口:不是基于函數簽名式,而是有效表達式組成的接口。如下圖,函數接口最終實例化成什么函數和模板參數T有關,在代碼編譯之前是不確定的。
在這里插入圖片描述

  • 運行期多態:在運行期虛函數指針根據指向對象確定哪一個虛函數該被綁定調用。
  • 編譯期多態:在編譯期以不同的模板參數具現化會導致調用不同的函數。
  • 對classes而言接口是顯式的(explicit),以函數簽名為中心。多態則是通過 virtual函數發生于運行期
  • 對template參數而言,接口是隱式的(implicit),奠基于有效表達式。多態則是通過template具現化和函數重載解析(function overloading resolution)發生于編譯期

條款42:了解typename的雙重意義

  • 當聲明template類型參數時,class和typename意義完全相同。建議使用typename
  • template內出現的名稱如果相依于某個template參數,稱之為從屬名稱(dependent names)。如果從屬名稱在 class內呈嵌套狀,我們稱它為嵌套從屬名稱(nested dependent name)。
  • 當嵌套從屬名稱表示一個類型時,需要加上typename前綴,表示是一個類型,也叫做嵌套從屬類型名稱;如果不加typename前綴,默認這個嵌套從屬名稱是一個非類型(例如某個類的靜態成員變量C::value)。
    在這里插入圖片描述
    在這里插入圖片描述
  • “typename必須作為嵌套從屬類型名稱的前綴詞”這一規則的例外是,**typename不可以出現在base classes list內的嵌套從屬類型名稱之前,也不可在member initialization list(成員初值列)中作為base class修飾符。**例如:
    在這里插入圖片描述
  • 對于冗長的嵌套從屬類型名稱可用typedef簡化
    在這里插入圖片描述

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

  • C++拒絕這個調用的原因:它知道base class templates有可能被特化,而那個特化版本可能不提供和一般性 template相同的接口。因此它往往拒絕在 templatized base classes(模板化基類,本例的MsgSender)內尋找繼承而來的名稱(本例的 sendClear)。實例化前編譯器不進入base class作用域內查找。就某種意義而言,當我們從Object Oriented C++跨進Template C++,繼承就不像以前那般暢行無阻了。
    在這里插入圖片描述

  • 解決方法統一思路:對編譯器承諾“base class template的任何特化版本都將支持其一般(泛化)版本所提供的接口”。

  • 解決方法1:在base class 函數調用動作之前加上“this->”
    在這里插入圖片描述

  • 解決方法2:使用using聲明式提前聲明模板基類函數
    在這里插入圖片描述

  • 解決方法3(不推薦):明確指出調用的函數位于模板基類里。若調用的是virtual函數,這種明確修飾會關閉“virtual綁定行為”(只會調用基類的虛函數,而不會調用繼承類中對應重寫的虛函數):
    在這里插入圖片描述

  • 編譯器的診斷時間可能發生在早期(當解析derived class template 的定義式時),也可能發生在晚期(當那些templates被特定之template 實參具現化時)。C++的政策是寧愿較早診斷,這就是為什么“當base classes 從templates中被具現化時”
    它假設它對那些baseclasses的內容毫無所悉的緣故。

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

  • 模板代碼膨脹:其二進制碼帶著重復(或幾乎重復)的代碼、數據,或兩者。其結果有可能源碼看起來合身而整齊,但目標碼(object code) 卻不是那么回事。
  • Templates生成多個classes和多個函數,所以任何template代碼都不該與某個造成膨脹的template參數產生相依關系。
  • 非類型模板參數(non- type template parameters) 而造成的代碼膨脹,往往可消除,做法是以函數參數或class成員變量替換template參數
  • 類型參數(type parameters)而造成的代碼膨脹,往往可降低,做法是讓帶有完全相同二進制表述( binary representations)的具現類型( instantiation types)共享實現碼
  • 有時愈是嘗試精密的做法,事情變得愈是復雜。從某個角度看,一點點代碼重復反倒看起來有點幸運了。需要在具體不同平臺進行衡量。

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

  • 以智能指針是“行為像指針”的對象,討論如何實現成員函數模板用于接受所有兼容類型,泛化智能指針操作類似指針操作。
  • 通過成員函數模板建立一個泛化的copy構造函數,使得該拷貝構造函數可以支持智能指針隱式轉換。這個行為只有當“存在某個隱式轉換可將-一個U指針轉為-一個T指針”時才能通過編譯,而那正是我們想要的。這個構造函數只在其所獲得的實參隸屬適當(兼容)類型時才通過編譯:
    在這里插入圖片描述
  • 通過成員函數模板建立一個泛化的賦值操作“=”函數。下圖所有構造函數都是explicit, 惟有“泛化copy構造函數”除外。那意味從某個shared_ ptr 類型隱式轉換至另一個shared ptr 類型是被允許的,但從某個內置指針或從其他智能指針類型進行隱式轉換則不被認可(如果是顯式轉換如cast強制轉型動作倒是可以)。
    在這里插入圖片描述
  • member templates 并不改變語言規則,而語言規則說,如果程序需要一個copy構造函數,你卻沒有聲明它,編譯器會為你暗自生成一個。 在class內聲明泛化copy構造函數(是個member template)并不會阻止編譯器生成它們自己的copy構造函數(一個non-template),所以如果你想要控制copy構造的方方面面,你必須同時聲明泛化copy構造函數和“正常的”copy構造函數。相同規則也適用于賦值( assignment)操作
    在這里插入圖片描述

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

  • 模板中,根據實參推導模板參數類型時不支持隱式類型轉換推導。如果一個模板類中,模板內的函數需要參數類型轉換,成員函數無法做到。函數參數隱式類型轉換之前需要確定該函數存在,而實例化之前成員函數并不存在。
  • 可在模板類內中采用friend函數聲明和定義,使其聲明跟隨模板類一起實例化,之后再調用的時候就可以自動找到該函數的聲明,進行隱式類型轉換(下圖中可在*重載中輸入int類型數據,使其隱式調用Rational的int類型構造函數,隱式轉換為Rational<int>)。
    在這里插入圖片描述
  • 由于定義于class內中的函數暗自成為inline,可采用class內中friend函數啥也不干,只調用一個外部輔助函數即可,減小inline聲明所帶來的沖擊
    在這里插入圖片描述

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

  • STL中迭代器可分為五類,繼承關系如下圖:
    (1). Input 迭代器,只能一步一步向前移動,只能讀取內容,且僅讀取一次。
    (2). Output 迭代器,只能一步一步向前移動,只能寫入內容,且僅寫入一次。
    (3). Forward 迭代器,只能一步一步向前移動,可讀可寫多次。
    (4). Bidirectianol 迭代器,只能一步一步向前或向后移動,可讀可寫多次。
    (5). Random Access 迭代器,可以在常量時間以任意步數向前或向后移動,可讀可寫多次。

在這里插入圖片描述

  • Traits是一種技術,也是一個C++程序員共同遵守的協議。它對內置類型和用戶自定義類型的表現必須一樣好

  • Traits設計實現流程(例子是實現advance模板函數,可以接受各種類型的迭代器進行移動):
    -(1)確認若干你希望將來可取得的類型信息;
    -(2)為該信息選一個名稱;
    在這里插入圖片描述
    -(3)提供一個template和一組特例化版本( 例特例化內置指針類型):
    在這里插入圖片描述
    在這里插入圖片描述

  • Traits classes使得“類型相關信息”在編譯期可用。它們以templates和“templates特化”完成實現。整合重載技術( overloading) 后,traitsclasses有可能在編譯期對類型執行if…else測試。(上述advance中有類型條件判單,是在運行期執行,可采用重載技術使其在編譯期進行,僅在advance函數中調用重載函數即可,如下圖)。
    在這里插入圖片描述

在這里插入圖片描述

  • 如何使用一個traits class:
    (1)建立一組重載函數 (身份像勞工)或函數模板(例如doAdvance) ,彼此間的差異只在于各自的traits參數。令每個函數實現碼與其接受之traits信息相應和。.
    (2)建立一個控制函數 (身份像工頭)或函數模板(例如advance) ,它調用上述那些“勞工函數”并傳遞traits class所提供的信息。

條款48:認識模板元編程

  • Template metaprogramming (TMP,模板元編程)可將工作由運行期移往編譯期,因而得以實現早期錯誤偵測和更高的執行效率。
  • TMP可被用來生成“基于政策選擇組合”的客戶定制代碼,也可用來避免生成對某些特殊類型并不適合的代碼。
  • 由于template metaprograms執行于C++編譯期,因此可將工作從運行期轉移到編譯期。這導致的一個結果是,某些錯誤原本通常在運行期才能偵測到,現在可在編譯期找出來。另一一個結果是,使用TMP的C++程序可能在每一方面都更高效:較小的可執行文件、較短的運行期、較少的內存需求。然而將工作從運行期移轉至編譯期的另一個結果是,編譯時間變長了
  • TMP中if…else…可通過模板函數重載實現;TMP循環結構可使用遞歸;TMP遞歸涉及遞歸模板具現化,如下圖計算階乘:
    在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/39492.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/39492.shtml
英文地址,請注明出處:http://en.pswp.cn/news/39492.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

opencv,opengl,osg,vulkan,webgL,opencL,cuda,osg,vtk,ogre的區別

OpenCV OpenCV是一個基于BSD許可&#xff08;開源&#xff09;發行的跨平臺計算機視覺和機器學習軟件庫&#xff0c;可以運行在Linux、Windows、Android和Mac OS操作系統上。 它輕量級而且高效——由一系列 C 函數和少量 C 類構成&#xff0c;同時提供了Python、Ruby、MATLAB等…

avue多選列表根據后端返回的某個值去判斷是否選中;avue-curd多選回顯

效果如上&#xff1a; getSiteList().then(res > {//列表數據this.siteData res.data.datathis.$nextTick(()>{this.siteData.forEach(item>{//業務條件if(item.configid&&item.configid!0&&item.configid>0){//符合條件時調用選中的方法this.$…

JAVASE---數組的定義與使用

數組的基本概念 什么是數組 數組是具有相同類型元素的集合&#xff0c;在內存中連續存儲。 1. 數組中存放的元素其類型相同 2. 數組的空間是連在一起的 3. 每個空間有自己的編號&#xff0c;起始位置的編號為0&#xff0c;即數組的下標 數組的創建及初始化 數組的創建 T[…

mybatis高級特性

文章目錄 數據庫事務管理批處理插件擴展持久化和ORM緩存機制 數據庫事務管理 通過注解方式&#xff1a; 在需要進行事務管理的方法上添加Transactional注解&#xff0c;該注解可以用于類或方法上。在配置文件中開啟事務管理器&#xff0c;并指定事務管理器的類型和連接池等相關…

Java SpringBoot Vue智能停車系統

基礎環境 JDK1.8、Maven、Mysql、IntelliJ IDEA 內置功能 系統管理&#xff1a;角色管理、接口管理、系統菜單、全局配置 賬號管理&#xff1a;用戶管理、合作單位 系統監控&#xff1a;監控大屏、日志監控 財務管理&#xff1a;訂單列表 停車記錄&#xff1a;停車記錄 車輛管…

Labview選項卡之實現被選擇選項卡工作

文章目錄 前言一、使用選項卡二、實現被選擇選項卡工作1、需求2、分析3、實現①、前面板②、程序框圖 三、效果展示四、源碼自取 前言 有些時候&#xff0c;我們做界面&#xff0c;需要好多個界面切換。如果是同一個 VI 里界面切換&#xff0c;一般都是選項卡了。切換不同選項…

使用phpstorm開發調試thinkphp

1.環境準備 1.開發工具下載&#xff1a;PhpStorm: PHP IDE and Code Editor from JetBrains 2.PHP下載&#xff1a;PHP: Downloads 3. PHP擴展&#xff1a;PECL :: Package search 4.用與調試的xdebug模塊&#xff1a; Xdebug: Downloads xdebug模塊&#xff0c;如果是php8以…

23.8.16日總結

原先寫的評論是每級評論用縮進來區分&#xff0c;所以最多設置的是九級評論&#xff0c;修改了排版和格式&#xff1a; 還有管理員頁面&#xff0c;查看文章時可以進行點贊&#xff0c;收藏的操作&#xff0c;現在進行了修改&#xff0c;將相關操作隱藏。 還有點擊查看未發布…

js如何獲取字符串大小是幾M

js如何獲取字符串大小是幾M 在JavaScript中&#xff0c;可以使用以下方法來獲取字符串的大小&#xff08;以字節為單位&#xff09;&#xff1a; function getStringSizeInBytes(str) {// 使用UTF-8編碼計算字符串的字節長度let totalBytes new Blob([str]).size;// 將字節長…

14-矩陣相乘及其運算法則

矩陣與向量的乘法 在這一篇文章中我們就將基于上一篇重新審視矩陣的這個視點來理解矩陣的乘法&#xff0c;那么在這一篇&#xff0c;我們主要來看一下矩陣和向量的乘法。這里這個線性方程組是上一小節給大家舉的模擬的一個非常簡單的小型經濟系統的例子&#xff0c;我們可以把…

文件的導入與導出

文章目錄 一、需求二、分析1. Excel 表格數據導出2. Excel 表格數據導入一、需求 在我們日常開發中,會有文件的導入導出的需求,如何在 vue 項目中寫導入導出功能呢 二、分析 以 Excel 表格數據導出為例 1. Excel 表格數據導出 調用接口將返回的數據進行 Blob 轉換,附: 接…

logstash日志換行處理小解

logstash主用于日志實時數據收集、解析&#xff0c;并將數據轉發的工具&#xff0c;內置的功能也相當強大。但&#xff0c;同時意味著&#xff0c;他可能接收到各種情況的數據。 此處&#xff0c;我們主要講解我實際使用中&#xff0c;碰到的一個小問題&#xff0c;換行(\n)。…

redis 和 mongodb 比較

Redis和MongoDB是兩種不同類型的數據庫&#xff0c;它們在數據存儲和查詢方式、數據模型以及適用場景等方面有一些明顯的區別。下面是Redis和MongoDB之間的一些比較&#xff1a; 數據模型&#xff1a; Redis&#xff1a;Redis是一個鍵值存儲系統&#xff0c;支持多種數據結構如…

FPGA應用學習筆記--時鐘域的控制 亞穩態的解決

時鐘域就是同一個時鐘的區域&#xff0c;體現在laways語句邊緣觸發語句中&#xff0c;設計規模增大就會導致時鐘不同步&#xff0c;有時差&#xff0c;就要設計多時鐘域。 會經過與門的延時產生的新時鐘域&#xff0c;這種其實不推薦使用&#xff0c;但在ascl里面很常見 在處理…

八大排序超詳解(動圖+源碼)

&#x1f493;博主個人主頁:不是笨小孩&#x1f440; ?專欄分類:數據結構與算法&#x1f440; 刷題專欄&#x1f440; C語言&#x1f440; &#x1f69a;代碼倉庫:笨小孩的代碼庫&#x1f440; ?社區&#xff1a;不是笨小孩&#x1f440; &#x1f339;歡迎大家三連關注&…

虛幻5中Lumen提供哪些功能以及如何工作的

虛幻引擎 5 中的 Lumen 是一個完全動態的全局照明和反射系統。它可以在虛幻引擎 5 中使用&#xff0c;因此創作者無需自行設置。它是為下一代控制臺和建筑可視化等高端可視化而設計的。那么它提供了哪些功能以及如何工作&#xff1f; 全局照明 當光離開光源時&#xff0c;它會…

負載均衡搭建

LVS-DR部署 [客戶端] node1 192.168.157.148 [lvs] node2 192.168.157.142 [web服務器] node3 192.168.157.145 node4 192.168.157.146&#xff08;1&#xff09;[lvs] yum install -y ipvsadm.x86_64 配置LVS負載均衡服務 &#xff08;1&#xff09;手動添加LVS轉發1&#xff…

系統架構設計專業技能 · 軟件工程之軟件測試與維護(六)【系統架構設計師】

系列文章目錄 系統架構設計專業技能 網絡規劃與設計&#xff08;三&#xff09;【系統架構設計師】 系統架構設計專業技能 系統安全分析與設計&#xff08;四&#xff09;【系統架構設計師】 系統架構設計高級技能 軟件架構設計&#xff08;一&#xff09;【系統架構設計師…

MAVEN利器:一文帶你了解MAVEN以及如何配置

前言&#xff1a; 強大的構建工具——Maven。作為Java生態系統中的重要組成部分&#xff0c;Maven為開發人員提供了一種簡單而高效的方式來構建、管理和發布Java項目。無論是小型項目還是大型企業級應用&#xff0c;Maven都能幫助開發人員輕松處理依賴管理、編譯、測試和部署等…

YOLOV7改進:加入RCS-OSA模塊,提升檢測速度

1.該文章屬于YOLOV5/YOLOV7/YOLOV8改進專欄,包含大量的改進方式,主要以2023年的最新文章和2022年的文章提出改進方式。 2.提供更加詳細的改進方法,如將注意力機制添加到網絡的不同位置,便于做實驗,也可以當做論文的創新點。 2.漲點效果:RCS-OSA模塊更加輕量化,有效提升檢…