c++primer第7章類-創(chuàng)新互聯(lián)

文章目錄
  • 第7章 類
    • 7.1 定義抽象數(shù)據(jù)類型
      • 7.1.1 設(shè)計(jì)Sales_data類
      • 7.1.2 定義改進(jìn)的Sales_data類
      • 7.1.3 定義類相關(guān)的非成員函數(shù)
      • 7.1.4 構(gòu)造函數(shù)
      • 7.1.5 拷貝、賦值和析構(gòu)
    • 7.2 訪問控制與封裝
      • 7.2.1 友元
    • 7.3 類的其他特性
      • 7.3.1 類成員再探
      • 7.3.2 返回*this的成員函數(shù)
      • 7.3.3 類類型
      • 7.3.4 友元再探
    • 7.4 類的作用域
      • 7.4.1 名字查找與類的作用域
    • 7.5 構(gòu)造函數(shù)再探
      • 7.5.1 構(gòu)造函數(shù)初始值列表
      • 7.5.2 委托構(gòu)造函數(shù)
      • 7.5.3 默認(rèn)構(gòu)造函數(shù)的作用
      • 7.5.4 隱式的類類型轉(zhuǎn)換
      • 7.5.5 聚合類
      • 7.5.6 字面值常量類
      • 7.6 類的靜態(tài)成員
    • 小結(jié)
    • 術(shù)語表

成都創(chuàng)新互聯(lián)公司專業(yè)為企業(yè)提供迎江網(wǎng)站建設(shè)、迎江做網(wǎng)站、迎江網(wǎng)站設(shè)計(jì)、迎江網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)與制作、迎江企業(yè)網(wǎng)站模板建站服務(wù),十年迎江做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。第7章 類
  • 使用類定義自己的數(shù)據(jù)類型
  • 數(shù)據(jù)抽象
    • 將對象的具體實(shí)現(xiàn)與對象所能執(zhí)行的操作分離開來
    • 依賴于接口和實(shí)現(xiàn)分離的編程技術(shù)
      • 接口:用戶所能執(zhí)行的操作
      • 實(shí)現(xiàn):類的數(shù)據(jù)成員、負(fù)責(zé)接口實(shí)現(xiàn)的函數(shù)體以及定義類所需的各種私有函數(shù)
  • 封裝
    • 實(shí)現(xiàn)類的接口和實(shí)現(xiàn)的分離
    • 影藏實(shí)現(xiàn)細(xì)節(jié),用戶只能訪問接口無法訪問實(shí)現(xiàn)
  • 抽象數(shù)據(jù)類型
    • 類的設(shè)計(jì)者:考慮類的實(shí)現(xiàn)過程
    • 使用類的程序員:抽象思考類型做了什么,無須了解類型工作細(xì)節(jié)
7.1 定義抽象數(shù)據(jù)類型
  • Sales_item類 抽象數(shù)據(jù)類型 通過接口使用對象 不能訪問類數(shù)據(jù)成員
  • Sales_data類 不是抽象數(shù)據(jù)類型 允許用戶直接訪問數(shù)據(jù)成員->封裝(隱藏)數(shù)據(jù)成員 變成抽象數(shù)據(jù)類型
7.1.1 設(shè)計(jì)Sales_data類
  • 定義成員函數(shù),先將其定義為普通函數(shù),執(zhí)行復(fù)合賦值運(yùn)算
  • 用戶 不同語境決定了不同的含義
    • 用戶代碼或類的使用者 程序員
    • 應(yīng)用程序使用者 如書店經(jīng)理
    • 設(shè)計(jì)類接口時(shí),應(yīng)考慮使類易于使用
    • 使用類時(shí),不應(yīng)顧及類的實(shí)現(xiàn)機(jī)理
    • 開發(fā)應(yīng)用程序,須充分了解用戶需求
    • 類設(shè)計(jì)者,應(yīng)關(guān)注使用類的程序員的需求
    • 良好設(shè)計(jì)的類,直觀易于使用的接口,高效的實(shí)現(xiàn)過程
  • 使用改進(jìn)的Sales_data類
7.1.2 定義改進(jìn)的Sales_data類
  • 定義在類內(nèi)部的函數(shù)隱式內(nèi)聯(lián)inline
  • 定義成員函數(shù)
    • 所有成員須在類內(nèi)部聲明,成員函數(shù)體可定義在類內(nèi)或類外
  • 引入this
    • 調(diào)用成員函數(shù),實(shí)際是在替某個(gè)對象調(diào)用它
    • 成員函數(shù)通過this隱式參數(shù),訪問調(diào)用它的對象
    • 調(diào)用成員函數(shù),用請求該函數(shù)的對象地址初始化this
    • 成員函數(shù)內(nèi)部,可直接使用該對象成員,無須成員訪問運(yùn)算符,對類成員的直接訪問看作this的隱式調(diào)用
    • 任何自定義名為this的參數(shù)或變量行為都是非法的
    • this總是指向調(diào)用該成員函數(shù)的對象,是一個(gè)常量指針,不允許改變this保存的地址
  • 引入const成員函數(shù)
    • const 修改隱式this指針的類型
    • 默認(rèn)情況下,this指向類類型非常量版本的常量指針,意味著不能將this綁定到常量對象上,故不能在常量對象上調(diào)用普通成員函數(shù)
    • 無須修改數(shù)據(jù)成員時(shí),將this設(shè)置為指向常量的指針有助于提高函數(shù)靈活性
    • 常量成員函數(shù):
      • 將const關(guān)鍵字放在成員函數(shù)的參數(shù)列表后,表示this是一個(gè)指向常量的指針
      • 不能改變調(diào)用它的對象的內(nèi)容,可以讀取數(shù)據(jù)成員,不能寫入新值
      • 常量對象/常量對象的引用或指針,都只能調(diào)用常量成員函數(shù)
  • 類作用域和成員函數(shù)
    • 類本身是一個(gè)作用域,類成員函數(shù)的定義嵌套在類的作用域內(nèi)
    • 編譯器分兩步處理類
        1. 先編譯成員函數(shù)聲明
        1. 才輪到成員函數(shù)體
      • 故成員函數(shù)體可隨意使用類成員其他函數(shù)無須在意成員出現(xiàn)次序
    • 在類的外部定義成員函數(shù)
      • 定義必須與聲明匹配
        • 返回類型/形參列表/函數(shù)名都需與類內(nèi)部聲明一致
      • 被聲明為常量成員函數(shù),定義也須在參數(shù)列表后指定const屬性
      • 類外部定義的成員名字必須包含它所屬的類名
      • 使用作用域運(yùn)算符::說明該函數(shù)被聲明在類內(nèi)部,剩余代碼是位于內(nèi)的作用域內(nèi)的
    • 定義一個(gè)返回this對象的指針
      • 當(dāng)定義函數(shù)類似于某個(gè)內(nèi)置類型運(yùn)算符時(shí),應(yīng)令該函數(shù)行為盡量模仿該運(yùn)算符
      • 返回對象引用類型,需將調(diào)用函數(shù)對象當(dāng)成一個(gè)整體訪問
        • return *this;解引用this指針以獲得執(zhí)行該函數(shù)的對象
7.1.3 定義類相關(guān)的非成員函數(shù)
  • 定義輔助函數(shù),概念上屬于類接口組成部分,實(shí)際上不屬于類本身
  • 非成員函數(shù)。通常將函數(shù)聲明和定義分離開來
  • 如果非成員函數(shù)是類的接口組成部分,函數(shù)聲明應(yīng)與類在同一個(gè)頭文件內(nèi)
  • 定義read和print函數(shù)
    • io類屬于不能被拷貝的類型,只能通過引用來傳遞他們
    • 讀取和寫入操作會改變流的內(nèi)容,故兩函數(shù)都接受普通引用
  • 定義add函數(shù)
    • 默認(rèn)情況下,拷貝類的對象拷貝的是對象的數(shù)據(jù)成員
7.1.4 構(gòu)造函數(shù)
  • 構(gòu)造函數(shù):定義類對象被初始化的方式,控制對象初始化過程,初始化類對象數(shù)據(jù)成員
  • 只要類的對象被創(chuàng)建,就會執(zhí)行構(gòu)造函數(shù)
  • 構(gòu)造函數(shù)名字與類名相同,沒有返回類型,也有一個(gè)參數(shù)列表和函數(shù)體
  • 類可包含多個(gè)構(gòu)造函數(shù),與其重載函數(shù)差不多,形參數(shù)量或類型須有區(qū)別
  • 構(gòu)造函數(shù)不能被聲明為const。當(dāng)創(chuàng)建類const對象時(shí),直到構(gòu)造函數(shù)完成初始化過程,對象才真正取得"常量"屬性。構(gòu)造函數(shù)在const對象構(gòu)造過程中可以向其寫值。
  • 合成的默認(rèn)構(gòu)造函數(shù)
    • 如果類沒有顯式定義構(gòu)造函數(shù),編譯器會隱式定義一個(gè)默認(rèn)構(gòu)造函數(shù)
    • 合成的默認(rèn)構(gòu)造函數(shù)初始化規(guī)則
      • 若存在類內(nèi)初始值,用其來初始化成員
      • 否則默認(rèn)初始化該成員
        • 默認(rèn)初始化:定義時(shí)沒指定初值變量被默認(rèn)初始化;內(nèi)置類型定義于函數(shù)體外初始化為0,定義于函數(shù)體內(nèi)則不被初始化。(建議初始化每一個(gè)內(nèi)置類型變量)
  • 某些類不能依賴于合成的默認(rèn)構(gòu)造函數(shù)
    • 普通類必須定義自己的默認(rèn)構(gòu)造函數(shù),原因有三
        1. 編譯器只會在我們沒有聲明任何構(gòu)造函數(shù)時(shí)會隱式定義一個(gè)默認(rèn)構(gòu)造函數(shù),一旦定義了其他構(gòu)造函數(shù),除非再定義一個(gè)默認(rèn)構(gòu)造函數(shù),否則類沒有默認(rèn)構(gòu)造函數(shù)
        1. 合成的默認(rèn)構(gòu)造函數(shù)可能執(zhí)行錯(cuò)誤的操作。定義在塊中的內(nèi)置類型(算術(shù)類型:字符 整型 浮點(diǎn)型 布爾型;空類型)/復(fù)合類型(數(shù)組和指針)的對象被默認(rèn)初始化則他們的值是未定義的,同樣適用于默認(rèn)初始化內(nèi)置類型成員。(只有當(dāng)類 內(nèi)置/復(fù)合類型的成員全部都被賦予類內(nèi)初始值時(shí),該類才適用于合成的默認(rèn)構(gòu)造函數(shù))
        1. 有時(shí)編譯器不能為某些類合成默認(rèn)構(gòu)造函數(shù)。(如:類中包含一個(gè)其他類類型成員且該成員類型沒有默認(rèn)構(gòu)造函數(shù),編譯器將無法初始化該成員。)必須自定義默認(rèn)構(gòu)造函數(shù),否則該類將沒有可用的默認(rèn)構(gòu)造函數(shù)。
  • 定義Sales_data的構(gòu)造函數(shù)
  • =default的含義
    • ales_data()=default;一個(gè)不接受任何實(shí)參的默認(rèn)構(gòu)造函數(shù)
    • 定義目的:既需要其他形式的構(gòu)造函數(shù),也需要默認(rèn)構(gòu)造函數(shù),希望該默認(rèn)構(gòu)造函數(shù)作用完全等同于合成默認(rèn)構(gòu)造函數(shù)
    • =default既可以和聲明一起出現(xiàn)在類的內(nèi)部(內(nèi)聯(lián)),也可以作為定義出現(xiàn)在類的外部
    • 若編譯器不支持類內(nèi)初始值,默認(rèn)構(gòu)造函數(shù)應(yīng)該使用構(gòu)造函數(shù)初始值列表來初始化類的每個(gè)成員
  • 構(gòu)造函數(shù)初始值列表
    • 負(fù)責(zé)為新創(chuàng)建的對象的一個(gè)或幾個(gè)數(shù)據(jù)成員賦值,如
Sales_data(const std::string &s):bookNo(s) {}
Sales_data(const std::string &s,unsigned n,double p):
           bookNo(s),uits_sold(n),revenue(p*n) {}
  • 當(dāng)某個(gè)數(shù)據(jù)成員被構(gòu)造函數(shù)初始值列表忽略時(shí),它將以合成默認(rèn)構(gòu)造函數(shù)相同的方式隱式初始化(如使用類內(nèi)初始值)
  • 若不能使用類內(nèi)初始值,則所有構(gòu)造函數(shù)都應(yīng)該顯式地初始化每個(gè)內(nèi)置類型的成員
  • 在類的外部定義構(gòu)造函數(shù)
    • 構(gòu)造函數(shù)無返回類型,定義從指定函數(shù)名開始,類外部定義構(gòu)造函數(shù),須指明構(gòu)造函數(shù)是哪個(gè)類的成員
7.1.5 拷貝、賦值和析構(gòu)
  • 拷貝:初始化變量以及以值的方式傳遞或返回一個(gè)對象
  • 賦值:使用賦值運(yùn)算符
  • 銷毀:對象不存在時(shí)執(zhí)行銷毀操作,局部對象會在創(chuàng)建它的塊結(jié)束時(shí)被銷毀,vector對象被銷毀時(shí)存儲在其中的對象也會被銷毀
  • 若不主動定義拷貝、賦值和析構(gòu)操作,編譯器會替我們合成它們
  • 某些類不能依賴于合成的版本
    • 當(dāng)類需要分配類對象之外的資源時(shí)(管理動態(tài)內(nèi)存的類)
    • 使用vector或string類能避免分配和釋放內(nèi)存帶來的復(fù)雜性,拷貝、賦值和析構(gòu)的合成版本能正常工作。(對含vector成員的對象執(zhí)行拷貝、賦值和析構(gòu)時(shí),會設(shè)法拷貝或賦值成員中的元素;對象被銷毀時(shí),將銷毀vector對象,依次銷毀vector中的每一個(gè)元素)
    • 類中所分配的資源都應(yīng)該直接以類的數(shù)據(jù)成員的形式存儲
7.2 訪問控制與封裝
  • 訪問說明符加強(qiáng)類的封裝性
    • public說明符后的成員在整個(gè)程序內(nèi)都可以被訪問,public成員定義類的接口
    • private說明符之后的成員可以被類的成員函數(shù)訪問,但不能被使用該類的代碼訪問,private部分封裝(隱藏)類的實(shí)現(xiàn)過程
  • 再次定義Sales_data類
    • public接口部分:構(gòu)造函數(shù)和部分成員函數(shù)
    • private實(shí)現(xiàn)部分:數(shù)據(jù)成員
  • 一個(gè)類可定義0/多個(gè)訪問說明符,每個(gè)說明符出現(xiàn)次數(shù)也沒有嚴(yán)格限定;每個(gè)說明符指定接下來的成員的訪問級別,有效范圍直到下一個(gè)訪問說明符或者到達(dá)類的結(jié)尾為止
  • 使用class或struct關(guān)鍵字
    • 唯一區(qū)別,class和struct的默認(rèn)訪問權(quán)限不太一樣
    • struct:定義在第一個(gè)說明符之前的成員是public的
    • class:定義在第一個(gè)說明符之前的成員是private的
    • 出于統(tǒng)一編程風(fēng)格:當(dāng)定義的類的所有成員是public時(shí),使用struct;當(dāng)定義的類的所有成員是private時(shí),使用class
7.2.1 友元
  • 類允許友元(其他類或者函數(shù))訪問它的非公有成員,只需增加一條friend關(guān)鍵字開始的函數(shù)聲明
  • 友元聲明只能出現(xiàn)在類定義的內(nèi)部,但出現(xiàn)位置不限;友元不是類的成員也不受所在區(qū)域訪問控制級別約束
  • 但一般最好在類定義開始或結(jié)束前的位置集中聲明友元
  • 封裝的益處
    • 確保用戶代碼不會無意間破環(huán)對象狀態(tài)
    • 數(shù)據(jù)成員定義為private的類作者可以較為自由地修改數(shù)據(jù);只要類的接口不變,用戶代碼就無須改變
    • 將查錯(cuò)限制在有限范圍內(nèi),極大降低維護(hù)代碼以及修成程序錯(cuò)誤地難度
    • 當(dāng)類的定義發(fā)生改變無須更改用戶代碼,但使用該類的源文件須重新編譯
  • 友元地聲明
    • 僅指定訪問權(quán)限,而非通常意義的函數(shù)聲明;類成員調(diào)用友元函數(shù)前須在友元聲明外再次聲明
    • 為使友元對類成員可見,通常將友元聲明與類本身放置在同一個(gè)頭文件中
    • 編譯器未強(qiáng)制限定友元函數(shù)須在使用之前在類的外部聲明;一些編譯器允許在尚無友元函數(shù)的初始聲明的情況下就調(diào)用它
7.3 類的其他特性
  • 類型成員、類的成員類內(nèi)初始值、可變數(shù)據(jù)成員、內(nèi)聯(lián)成員函數(shù)、從成員函數(shù)返回*this、如何定義類類型以及友元類
7.3.1 類成員再探
  • 定義一個(gè)類型成員
    • 自定義某種類型在類中的別名,與其他成員一樣存在訪問限制(public/private)
    • 用來定義類型的成員必須先定義后使用,因此類型成員通常出現(xiàn)在類開始的地方
  • Screen類的成員函數(shù)
  • 令成員作為內(nèi)聯(lián)函數(shù)
    • 定義在類內(nèi)部的成員函數(shù)自動inline
    • 可以在類內(nèi)部作為聲明的一部分顯示聲明成員函數(shù),也能在類的外部用inline關(guān)鍵字修飾函數(shù)的定義
    • 雖無須在聲明和定義同時(shí)說明inline但合法,最好只在類外部定義的地方說明inline使類更容易理解
    • 和在頭文件中定義inline函數(shù)原因一樣(編譯器想展開函數(shù)不僅需要函數(shù)聲明還需要函數(shù)定義,且多個(gè)定義須完全一致),inline成員函數(shù)也應(yīng)該與相應(yīng)的類定義在同一個(gè)頭文件中
  • 重載成員函數(shù)
    • 參數(shù)數(shù)量/類型上有所區(qū)別
  • 可變數(shù)據(jù)成員
    • 即使在const成員函數(shù)內(nèi)也能修改某個(gè)數(shù)據(jù)成員,通過在變量聲明前加mutable關(guān)鍵字
    • 可變數(shù)據(jù)成員永遠(yuǎn)也不會是const,即使它是const對象的成員(可用于記錄const成員函數(shù)被調(diào)用的次數(shù))
  • 類數(shù)據(jù)成員的初始值
    • 類內(nèi)初始值必須用=的初始化形式
    • 或花括號括起來的直接初始化形式
7.3.2 返回*this的成員函數(shù)
  • 定義返回為引用時(shí)返回對象本身而非對象副本,返回類型為非引用時(shí)返回*this的副本
  • 從const成員函數(shù)返回*this
    • 一個(gè)const成員函數(shù)如果以引用的形式返回*this,那么它的返回類型將是常量引用
  • 基于const的重載
    • 通過成員函數(shù)是否是const的可對其進(jìn)行重載,原因與根據(jù)指針參數(shù)是否指向const而重載差不多(非常量版本函數(shù)對常量對象不可用,只能在常量對象上調(diào)用const成員函數(shù);非常量對象可調(diào)用常量/非常量版本,但非常量版本是更好的匹配;根據(jù)對象是否是const決定了應(yīng)該調(diào)用的函數(shù)版本)
    • 當(dāng)一個(gè)成員調(diào)用另一個(gè)成員是,this指針在其中隱式傳遞
  • 對于公共代碼使用私有功能函數(shù)
    • 避免在多處使用同樣的代碼
    • 類規(guī)模發(fā)展,函數(shù)變得更復(fù)雜,將相同操作寫在一處較好
    • 可能在函數(shù)中添加某些調(diào)試信息,在一處添/刪更容易
    • 額外調(diào)用不增加開銷,因?yàn)樵陬悆?nèi)部定義,隱式地被聲明為內(nèi)聯(lián)函數(shù)
7.3.3 類類型
  • 每個(gè)類定義唯一類型;兩個(gè)類即使成員(列表)完全一樣,兩個(gè)類也是不同的類型
  • 一個(gè)類的成員和其他任何類(或任何其他作用域)地成員都不是一回事
  • 可直接使用類名作為類型名,也可把類名跟在關(guān)鍵字class或struct后面
  • 類的聲明
    • 前向聲明:僅僅聲明類而暫時(shí)不定義它
    • 不完全類型:聲明之后定義之前(只能在非常有限的的情境下使用)
      • 可以定義指向這種類型的指針或引用
      • 也可以聲明(但不能定義)以不完全類型作為參數(shù)或者返回類型的函數(shù)
    • 創(chuàng)建類對象時(shí)該類必須被定義過,不能僅被聲明(編譯器無法了解對象所需儲存空間)
    • 類須先被定義才能用引用或指針訪問其成員(否則編譯器不清楚該類有哪些成員)
    • 直到類被定義后數(shù)據(jù)成員才能被聲明成這種類型,一個(gè)類成員的類型不能是類自己;但類允許包含指向它自身類型的引用或指針
7.3.4 友元再探
  • 可以將非成員函數(shù)/其他類/其他類已定義過的成員函數(shù)定義成友元
  • 友元函數(shù)能定義在類的內(nèi)部 隱式內(nèi)聯(lián)
  • 類之間的友元關(guān)系friend class Window_mgr;
    • 友元類的成員函數(shù)可以訪問此類包括非共有成員在內(nèi)的所有成員
    • 友元關(guān)系不存在傳遞性,(即類A存在友元類B,類B存在友元類C,則類C不具有訪問類A特權(quán))
    • 每個(gè)類負(fù)責(zé)控制自己的友元類或友元函數(shù)
  • 令成員函數(shù)作為友元
    • 當(dāng)將成員函數(shù)聲明成友元時(shí),須明確指出該成員函數(shù)屬于哪個(gè)類
    • 須仔細(xì)組織程序的結(jié)構(gòu)以滿足聲明和定義的彼此依賴關(guān)系,設(shè)計(jì)程序的方式如下
      • 先定義類A,聲明a函數(shù),但不能定義它;在a使用類B的成員之前必須先聲明類B
      • 接下來定義類B,包括對于a的友元聲明
      • 最后定義函數(shù)a,此時(shí)a才可以使用類B的成員
  • 函數(shù)重載和友元
    • 如想將一組重載函數(shù)聲明成友元,需對這組函數(shù)中的每一個(gè)分別聲明
  • 友元聲明和作用域
    • 友元聲明的作用是影響訪問權(quán)限,本身并非普通意義上的聲明
    • 就算在類的內(nèi)部定義友元函數(shù),也須在類的外部提供相應(yīng)聲明使函數(shù)可見
    • 類的成員使用友元函數(shù)時(shí),友元函數(shù)也須先被聲明過
    • 有的編譯器不強(qiáng)制執(zhí)行上述關(guān)于友元的限定規(guī)則
7.4 類的作用域
  • 一個(gè)類就是一個(gè)作用域
  • 類的作用域之外,普通數(shù)據(jù)和函數(shù)成員只能由對象、引用或者指針使用成員訪問運(yùn)算符訪問
  • 類類型成員則使用作用域訪問符訪問
  • 跟在類作用域運(yùn)算符之后的名字都須是對應(yīng)類的成員
  • 作用域和定義在類外部的成員
    • 一個(gè)類就是一個(gè)作用域,在類的外部定義成員函數(shù)時(shí)必須同時(shí)提供類名和函數(shù)名(類的外部,成員名字被隱藏)
    • 一旦遇到類名,定義剩余部分就在類的作用域之內(nèi)了,包括參數(shù)列表和函數(shù)體(內(nèi)可直接使用類的其他成員而無須再次授權(quán))
    • 函數(shù)返回類型在函數(shù)名之前,當(dāng)函數(shù)定義在類外部時(shí),返回類型名字位于作用域之外,因此返回類型須指明它是哪個(gè)類的成員
7.4.1 名字查找與類的作用域
  • 名字查找
    • 在名字所在塊中尋找聲明語句,只考慮在名字試用前的聲明
    • 若沒找到,繼續(xù)查找外層作用域
    • 若最終沒找到匹配的聲明,程序報(bào)錯(cuò)
  • 定義在類內(nèi)部的成員
    • 編譯器先編譯成員的聲明
    • 直到類全部可見后才編譯函數(shù)體(處理完全部聲明后才會處理成員函數(shù)定義)
    • 所以定義在類內(nèi)部的成員函數(shù)體能使用類定義中的任何名字
  • 用于類成員聲明的名字查找
    • 兩階段處理只適用于定義在類內(nèi)的成員函數(shù)體中使用的名字
    • 聲明中使用的返回類型/參數(shù)列表的名字,都須在使用前確??梢?/li>
    • 若函數(shù)聲明使用了類中尚未出現(xiàn)的名字,則編譯器將在定義該類的作用域中繼續(xù)查找
  • 類型名要特殊處理
    • 內(nèi)層作用域可以重新定義外層作用域中的名字
    • 但若成員使用了外層作用域中的類型名字,則類中不能在之后重新定義該名字
      • 重新定義類型名字是一種錯(cuò)誤的行為
      • 類型名定義放在類開始處,能確保所有使用類型的成員都在類名定義后
  • 成員定義中的普通塊作用域的名字查找
    • 先在成員函數(shù)內(nèi)查找名字聲明,在使用前的才有效
    • 成員函數(shù)內(nèi)沒有,則在類內(nèi)繼續(xù)查找,類的所有成員都可以被考慮
    • 類內(nèi)也沒有該名字的聲明則在成員函數(shù)定義前的作用域內(nèi)繼續(xù)查找
    • (不建議使用其他成員的名字作為某個(gè)成員函數(shù)的參數(shù),成員函數(shù)參數(shù)會隱藏外層同名參數(shù);但仍可通過加上類的名字或顯式使用this指針來強(qiáng)制訪問成員)
  • 類作用域之后,在外圍的作用域中查找
    • 編譯器在函數(shù)和類的作用域中都沒找到名字,將接著在外圍作用域中查找
    • 可顯式通過作用域運(yùn)算符來進(jìn)行請求外層作用域中的名字(::前什么都沒有表示全局作用域)
  • 在文件中名字的出現(xiàn)處對其進(jìn)行解析
    • 當(dāng)成員定義在類的外部時(shí),不僅須考慮定義前的全局作用域中的聲明,還需考慮成員函數(shù)定義前的全局作用域中的聲明
7.5 構(gòu)造函數(shù)再探 7.5.1 構(gòu)造函數(shù)初始值列表
  • 定義變量時(shí)習(xí)慣立即對其進(jìn)行初始化而非先定義再賦值
  • 若沒有在構(gòu)造函數(shù)初始值列表中顯式初始化成員,則成員在構(gòu)造函數(shù)體之前執(zhí)行默認(rèn)初始化
  • 使用構(gòu)造函數(shù)初始值列表與在構(gòu)造函數(shù)體內(nèi)對數(shù)據(jù)成員執(zhí)行賦值的效果相同。但深層次的影響完全依賴于數(shù)據(jù)成員的類型
  • 構(gòu)造函數(shù)的初始值有時(shí)必不可少
    • 有時(shí)可忽略數(shù)據(jù)成員初始化與賦值之間的差異
    • 但若成員是const或引用則須將其初始化
    • 當(dāng)成員屬于某種沒有定義默認(rèn)構(gòu)造函數(shù)的類的類型時(shí)也須初始化
    • (隨著函數(shù)體一開始執(zhí)行,初始化就完成了,初始化const或引用類型數(shù)據(jù)成員的唯一機(jī)會就是構(gòu)造函數(shù)初始值)
    • 很多類中 初始化(直接初始化數(shù)據(jù)成員)和賦值(先初始化再賦值)事關(guān)底層效率
    • 一些數(shù)據(jù)成員必須被初始化,養(yǎng)成使用構(gòu)造函數(shù)初始值的習(xí)慣,能避免一些意想不到的編譯錯(cuò)誤
  • 成員初始化的順序
    • 構(gòu)造函數(shù)初始值中每個(gè)成員只能出現(xiàn)一次
    • 成員初始化順序與在類定義的出現(xiàn)順序一致,與初始值列表中的前后位置無關(guān)
    • 最好令構(gòu)造函數(shù)初始值的順序與成員聲明的順序保持一致,盡量避免使用某些成員初始化其他成員,如可能最好使用構(gòu)造函數(shù)參數(shù)作為成員初始值(可不必考慮成員初始化順序)
  • 默認(rèn)實(shí)參和構(gòu)造函數(shù)
    • 如果一個(gè)構(gòu)造函數(shù)為所有參數(shù)都提供了默認(rèn)實(shí)參,則實(shí)際上也定義了默認(rèn)構(gòu)造函數(shù)(因?yàn)榭梢圆惶峁?shí)參也能調(diào)用上述函數(shù))
7.5.2 委托構(gòu)造函數(shù)
  • 委托構(gòu)造函數(shù)使用它所屬類的其他構(gòu)造函數(shù)執(zhí)行它自己的初始化過程(將自己的一些/全部職責(zé)委托給其他構(gòu)造函數(shù))
    • 也有一個(gè)成員初始值列表和函數(shù)體,成員初始值列表唯一入口是類名本身,參數(shù)列表須與類中另外一個(gè)構(gòu)造函數(shù)匹配
    • 當(dāng)一個(gè)構(gòu)造函數(shù)委托另一個(gè)構(gòu)造函數(shù)時(shí),先執(zhí)行受委托函數(shù)的初始值列表和函數(shù)體執(zhí)行完后控制權(quán)才會交還給委托者的函數(shù)體
7.5.3 默認(rèn)構(gòu)造函數(shù)的作用
  • 當(dāng)對象在默認(rèn)初始化或者值初始化時(shí)自動執(zhí)行默認(rèn)構(gòu)造函數(shù)
    • 默認(rèn)初始化
      • 在塊作用域內(nèi)不使用任何初始值定義一個(gè)非靜態(tài)變量/數(shù)組
      • 當(dāng)一個(gè)類本身含有類類型成員且使用合成的默認(rèn)構(gòu)造函數(shù)時(shí)
      • 當(dāng)類類型成員沒有在構(gòu)造函數(shù)初始值列表中顯式初始化時(shí)
    • 值初始化
      • 數(shù)組初始化時(shí)提供初始值數(shù)量少于數(shù)組大小時(shí)
      • 當(dāng)不使用初始值定義一個(gè)局部靜態(tài)變量時(shí)
      • 通過書寫形如T()(其中T為類型名稱)的表達(dá)式顯式請求值初始化時(shí)
    • 如果定義了其他構(gòu)造函數(shù),那么最好也提供一個(gè)默認(rèn)構(gòu)造函數(shù)
  • 使用默認(rèn)構(gòu)造函數(shù)
    • 如想定義一個(gè)使用默認(rèn)構(gòu)造函數(shù)進(jìn)行值初始化的對象,正確方法是去掉對象名后的空括號(有空括號會當(dāng)成一個(gè)不接受任何參數(shù),返回值為類類型的函數(shù))
7.5.4 隱式的類類型轉(zhuǎn)換
  • 轉(zhuǎn)換構(gòu)造函數(shù)
    • 如果構(gòu)造函數(shù)只接受一個(gè)實(shí)參,則實(shí)際上定義了轉(zhuǎn)換為此類類型的隱式轉(zhuǎn)換機(jī)制
    • 通過一個(gè)實(shí)參調(diào)用的構(gòu)造函數(shù)定義了一條從構(gòu)造函數(shù)的參數(shù)類型向類類型隱式轉(zhuǎn)換的規(guī)則
    • 編譯器用給定的參數(shù)自動創(chuàng)建一個(gè)(臨時(shí))類對象(可以給常量引用的參數(shù)傳遞臨時(shí)量)
  • 只允許一步類類型轉(zhuǎn)換
    • 編譯器只會自動地執(zhí)行一步類型轉(zhuǎn)換,當(dāng)隱式使用兩種或以上轉(zhuǎn)換規(guī)則則是錯(cuò)誤的
  • 類類型轉(zhuǎn)換不是總有效
    • 實(shí)際上構(gòu)造了一個(gè)臨時(shí)對象,一旦操作完,隨后就將其丟棄不能夠再訪問了
  • 抑制構(gòu)造函數(shù)定義的隱式轉(zhuǎn)換
    • 在要求隱式轉(zhuǎn)換的程序的上下文,可通過將構(gòu)造函數(shù)聲明為explicit加以阻止隱式轉(zhuǎn)換
    • 關(guān)鍵字explicit只對一個(gè)實(shí)參的構(gòu)造函數(shù)有效;
    • 需多個(gè)實(shí)參的構(gòu)造函數(shù)不能用于執(zhí)行隱式轉(zhuǎn)換,所以也無須指定為explicit
    • 只能在類內(nèi)聲明構(gòu)造函數(shù)時(shí)使用explicit關(guān)鍵字,在類外部定義時(shí)不應(yīng)重復(fù)
  • explicit構(gòu)造函數(shù)只能用于直接初始化
    • 不能將explicit構(gòu)造函數(shù)用于拷貝形式的初始化過程
    • explicit關(guān)鍵字聲明構(gòu)造函數(shù)時(shí),只能以直接初始化的形式使用,編譯器將不會在自動轉(zhuǎn)換過程中使用該構(gòu)造函數(shù)
  • 為轉(zhuǎn)換顯式地使用構(gòu)造函數(shù)
    • 編譯器不會為explicit構(gòu)造函數(shù)用于隱式轉(zhuǎn)換過程,但可以使用該構(gòu)造函數(shù)顯式地強(qiáng)制進(jìn)行類型轉(zhuǎn)換(也可利用static_cast使用explicit構(gòu)造函數(shù)),創(chuàng)建的都是臨時(shí)類對象
  • 標(biāo)準(zhǔn)庫中含有顯式構(gòu)造函數(shù)(單參數(shù))的類
    • 接受一個(gè)單參數(shù)的const char*的string構(gòu)造函數(shù)(不是explicit的)
    • 接受一個(gè)容器參數(shù)的vector構(gòu)造函數(shù)(是explicit的)
7.5.5 聚合類
  • 聚合類 使用戶可以直接訪問其成員,具有特殊初始化語法形式
    • 所有成員都是public的
    • 沒有定義任何構(gòu)造函數(shù)
    • 沒有類內(nèi)初始值
    • 沒有基類,也沒有virtual函數(shù)
  • 可以提供一個(gè)花括號括起來的成員初始值列表,用它初始化聚合類的數(shù)據(jù)成員,初始值的順序必須與聲明的順序一致
    • 與初始化數(shù)組一樣,如果初始值列表中的元素個(gè)數(shù)少于類的成員數(shù)量,靠后的成員被值初始化;初始化列表的元素個(gè)數(shù)絕對不能超過類的成員數(shù)量
  • 顯式初始化類對象成員的三個(gè)明顯缺點(diǎn)
    • 要求類的所有成員都是public的
    • 將正確初始化類每個(gè)對象的重任交給了類的用戶,用戶易忘掉某個(gè)初始值或提供一個(gè)不恰當(dāng)?shù)某跏贾担跏蓟^程冗長乏味且容易出錯(cuò)
    • 添加或刪除一個(gè)成員后,所有初始化語句都需更新
7.5.6 字面值常量類
  • constexpr函數(shù)的參數(shù)和返回值必須是字面值類型( 字面值類型:算術(shù)類型 引用 指針; 不屬于字面值類型: 某些自定義類 IO庫 string)
  • 字面值類型的類可能含有constexpr函數(shù)成員,該成員須符合constexpr函數(shù)的所有要求,是隱式const的
  • 數(shù)據(jù)成員都是字面值類型的聚合類是字面值常量類,若某類不是聚合類但符合以下要求,則也是字面值常量類
    • 數(shù)據(jù)成員都須是字面值類型
    • 類須至少含有一個(gè)constexpr構(gòu)造函數(shù)
    • 若數(shù)據(jù)成員含有類內(nèi)初始值,則內(nèi)置類型成員的初始值必須是一條常量表達(dá)式;若成員屬于某種類類型,則初始值必須使用成員自己的constexpr構(gòu)造函數(shù)
    • 類須使用析構(gòu)函數(shù)的默認(rèn)定義(負(fù)責(zé)銷毀類的對象)
  • constexpr構(gòu)造函數(shù)
    • 構(gòu)造函數(shù)不能是const的,但字面值常量類的構(gòu)造函數(shù)可以是constexpr函數(shù)
    • constexpr構(gòu)造函數(shù)可聲明成=default的形式或者刪除函數(shù)的形式;否則構(gòu)造函數(shù)就須既符合構(gòu)造函數(shù)要求(不能包含返回語句),又符合constexpr函數(shù)的要求(唯一可執(zhí)行語句就是返回語句)->constexpr構(gòu)造函數(shù)體一般是空的
    • 前置關(guān)鍵字constexpr就可以聲明一個(gè)constexpr構(gòu)造函數(shù)
    • constexpr構(gòu)造函數(shù)須初始化所有數(shù)據(jù)成員,初始值或者使用constexpr構(gòu)造函數(shù)或者是一條常量表達(dá)式
    • constexpr構(gòu)造函數(shù)用于生成constexpr對象以及constexpr函數(shù)函數(shù)的參數(shù)或返回類型
7.6 類的靜態(tài)成員
  • 有時(shí)類需要它的一些成員與類本身直接相關(guān),而不是與類的各個(gè)對象保持關(guān)聯(lián)
  • 聲明靜態(tài)成員
    • 在類成員聲明前加static使其與類關(guān)聯(lián)在一起
    • 靜態(tài)成員可以是public或private的;靜態(tài)數(shù)據(jù)成員的類型可以是常量/引用/指針/類類型
    • 類靜態(tài)成員存在于任何對象之外,對象中不包含任何與靜態(tài)數(shù)據(jù)成員有關(guān)的數(shù)據(jù)。被所有類對象共享
    • 類靜態(tài)成員函數(shù)也不與任何對象綁定在一起,不包含this指針;靜態(tài)成員函數(shù)不能聲明成const的,也不能在static函數(shù)體內(nèi)使用this指針(這限制適用于this的顯式使用,也對調(diào)用非靜態(tài)成員的隱式使用有效)
  • 使用類的靜態(tài)成員
    • 使用作用域運(yùn)算符直接訪問靜態(tài)成員
    • 靜態(tài)成員雖不屬于類的某個(gè)對象,但仍可使用類對象、引用或指針來訪問靜態(tài)成員
    • 成員函數(shù)不用通過作用域運(yùn)算符就能直接使用靜態(tài)成員
  • 定義靜態(tài)成員
    • 與其他成員函數(shù)一樣,既可以在類的內(nèi)部也可以在類的外部定義靜態(tài)成員函數(shù)
    • 在類外部定義靜態(tài)成員時(shí),不能重復(fù)static關(guān)鍵字,static值出現(xiàn)在類內(nèi)部聲明語句
    • 指向類外部靜態(tài)成員時(shí),須指明成員所屬類名
    • 靜態(tài)成員不屬于類的任何對象,它們不是在創(chuàng)建類的對象時(shí)被定義的,它們不由類的構(gòu)造函數(shù)初始化;
    • 一般不能在類的內(nèi)部初始化靜態(tài)成員,須在類的外部定義和初始化每個(gè)靜態(tài)成員,一個(gè)靜態(tài)數(shù)據(jù)成員只能定義一次
    • 類似全局變量,類靜態(tài)數(shù)據(jù)成員定義在任何函數(shù)之外;一旦被定義,就將一直存在于程序的整個(gè)生命周期中
    • 在類外部定義靜態(tài)數(shù)據(jù)成員,需指定對象類型名,類名、作用域運(yùn)算符、成員自己的名字;從類名開始,定義語句的剩余部分都位于類的作用域之內(nèi),(可以訪問類的私有成員)
    • 為確保對象只定義一次,最好把靜態(tài)成員的定義與其他非內(nèi)聯(lián)函數(shù)的定義放在同一個(gè)文件中
  • 靜態(tài)成員的類內(nèi)初始化
    • 通常類靜態(tài)成員不應(yīng)在類內(nèi)部初始化,但可為靜態(tài)成員提供const整數(shù)型的類內(nèi)初始值,不過要求靜態(tài)成員須是字面值常量類型的constexpr。初始值須是常量表達(dá)式,因成員本身就是常量表達(dá)式,所以可用于所有適合常量表達(dá)式的地方。(初始化了的靜態(tài)數(shù)據(jù)成員可用于指定數(shù)組維度)
    • 若靜態(tài)成員的應(yīng)用場景僅限于編譯器可以替換它的值,則一個(gè)初始化的const或constexpr static不需要分別定義;若將它用于值不能替換的場景中,則該成員須有一條定義語句
    • 若在類的內(nèi)部提供了一個(gè)初始值,則成員定義不能再指定一個(gè)初始值
    • 即使一個(gè)常量靜態(tài)數(shù)據(jù)成員在類內(nèi)部被初始化了,通常也應(yīng)在內(nèi)的外部定義一下該成員
  • 靜態(tài)成員能用于某些場景,而普通成員不能
    • 靜態(tài)成員獨(dú)立于任何對象,某些非靜態(tài)數(shù)據(jù)成員可能非法的場合,靜態(tài)成員可以正常使用
    • 靜態(tài)數(shù)據(jù)成員可以是不完全類型(聲明之后定義之前)
    • 靜態(tài)數(shù)據(jù)成員的類型可以是它所屬類類型;非靜態(tài)數(shù)據(jù)成員則受到限制,只能聲明成它所屬類的指針或引用
    • 可以使用靜態(tài)數(shù)據(jù)成員作為默認(rèn)實(shí)參,非靜態(tài)成員不能作為默認(rèn)實(shí)參(值本身屬于對象一部分,無法真正提供一個(gè)對象以便從中獲取成員的值)
小結(jié)
  • 類 定義新類型 使程序更簡潔且易于修改
  • 類兩項(xiàng)基本能力
      1. 數(shù)據(jù)抽象 定義數(shù)據(jù)成員和成員函數(shù)的能力
      1. 封裝 保護(hù)類的成員不被隨意訪問的能力(private)
      • 類可將其他類或函數(shù)設(shè)為友元,使它們能訪問類非共有成員
  • 類可定義特殊成員:構(gòu)造函數(shù)
    • 控制初始化對象的方式
    • 可以重載
    • 應(yīng)使用構(gòu)造函數(shù)初始值列表來初始化所有數(shù)據(jù)成員
  • 類可定義可變或靜態(tài)成員
    • 一個(gè)可變成員(mutable)永遠(yuǎn)不會是const,在const函數(shù)內(nèi)也能修改它的值
    • 靜態(tài)成員可以是函數(shù)或數(shù)據(jù),存在于所有對象之外
術(shù)語表
  • 轉(zhuǎn)換構(gòu)造函數(shù):可用一個(gè)實(shí)參調(diào)用的非顯式構(gòu)造函數(shù)(隱式將參數(shù)類型轉(zhuǎn)換為類類型)
  • 數(shù)據(jù)抽象:關(guān)注類型接口的編程技術(shù);忽略類型實(shí)現(xiàn)細(xì)節(jié)只關(guān)注類型執(zhí)行操作;數(shù)據(jù)抽象是面向?qū)ο缶幊毯头盒途幊袒A(chǔ)
  • 顯式構(gòu)造函數(shù):可以用一個(gè)單獨(dú)的實(shí)參調(diào)用但是不能用于隱式轉(zhuǎn)換的構(gòu)造函數(shù)(構(gòu)造函數(shù)聲明前加explicit)
  • 前向聲明:尚未定義名字前的聲明
  • 實(shí)現(xiàn):類的成員(通常是私有的)定義了不希望使用類類型的代碼所使用的數(shù)據(jù)及任何操作
  • 不完全類型:已經(jīng)聲明但是尚未定義的類型;不能用于定義變量或類的成員,但可用于定義指針或引用
  • 接口:類提供的(公有)操作

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧

分享文章:c++primer第7章類-創(chuàng)新互聯(lián)
網(wǎng)址分享:http://www.muchs.cn/article28/deoecp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App開發(fā)、服務(wù)器托管、網(wǎng)站導(dǎo)航、品牌網(wǎng)站設(shè)計(jì)、做網(wǎng)站、虛擬主機(jī)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)