類是面向?qū)ο缶幊痰幕A(chǔ)肥败,使用類定義自己的數(shù)據(jù)類型族跛,可以更方便的解決問題中的各種概念,使我們更容易編寫举娩、調(diào)試和修改程序析校。
7.1 定義抽象的數(shù)據(jù)類型
- 定義在類內(nèi)部的函數(shù)時隱式的inline函數(shù)。
- 類的所有成員都必須在類的內(nèi)部聲明铜涉,但是成員函數(shù)體可以定義在類的內(nèi)部或外部智玻。
- 成員函數(shù)通過一個名為this的額外的隱式參數(shù)來訪問調(diào)用它的那個對象。當(dāng)我們調(diào)用一個成員函數(shù)時芙代,用請求該函數(shù)的對象地址初始化this吊奢。
- 成員函數(shù)體可以隨意使用類中的其他成員而不需要在意這些成員出現(xiàn)的次序。
構(gòu)造函數(shù)
編譯器創(chuàng)建的構(gòu)造函數(shù)又被稱為合成的默認(rèn)構(gòu)造函數(shù)纹烹,合成的默認(rèn)構(gòu)造函數(shù)初始化類的數(shù)據(jù)成員規(guī)則為:存在類內(nèi)初始值的時候页滚,用它來初始化成員召边;否則,默認(rèn)初始化該成員逻谦。
對于一個普通的類掌实,一般要定義自己的默認(rèn)構(gòu)造函數(shù):
- 編譯器只有在發(fā)現(xiàn)類不包含任何構(gòu)造函數(shù)的情況下才會替我們生成一個默認(rèn)的構(gòu)造函數(shù)。
- 對于某些類來說邦马,合成的默認(rèn)構(gòu)造函數(shù)可能執(zhí)行錯誤的操作贱鼻。
- 有的時候編譯器不能為某些類合成默認(rèn)的構(gòu)造函數(shù)。
- 構(gòu)造函數(shù)沒有返回類型滋将。
拷貝邻悬。賦值和析構(gòu)
除了定義類的對象如何初始化之外,類還需要控制拷貝随闽、賦值和銷毀對象的時候發(fā)生的行為父丰。
當(dāng)我們不主動定義這些操作的的時候,編譯器將替我們合成他們掘宪。但是有些類不能依賴于合成的版本蛾扇。當(dāng)類需要分配類對象之外的資源時,合成的版本常常會失效魏滚。
7.2 訪問控制與封裝
在類的定義中镀首,可以包含0個或多個訪問說明符,每個訪問說明符指定接下來的成員訪問級別鼠次,一般來說更哄,作為接口的一部分,構(gòu)造函數(shù)和一部分成員函數(shù)應(yīng)該定義在public說明符之后腥寇,而數(shù)據(jù)成員和作為實(shí)現(xiàn)部分的函數(shù)跟在private說明符之后成翩。
class和struct唯一的區(qū)別是默認(rèn)訪問權(quán)限不同。
7.3 類的其他特性
類型成員赦役、類的成員的類內(nèi)初始值麻敌、可變數(shù)據(jù)成員、內(nèi)聯(lián)數(shù)據(jù)成員扩劝、從成員函數(shù)返回*this庸论、關(guān)于如何定義類類型及友元類等。
類成員
除了定義數(shù)據(jù)和函數(shù)成員之外棒呛,類還可以自定義某種類型在類中的別名聂示。由類定義的類型名字和其他成員一樣存在訪問限制。
另成員作為內(nèi)聯(lián)函數(shù)
在類中簇秒,一些規(guī)模較小的函數(shù)常被定義為內(nèi)聯(lián)函數(shù)
兩種方式:1鱼喉、直接把函數(shù)定義放在類的內(nèi)部
2、把函數(shù)定義放在類的外部,顯式的使用inline
- 一個const成員函數(shù)如果以引用的形式返回*this扛禽,那么它的返回類型將是常量引用锋边。
- 在實(shí)踐中,設(shè)計良好的代碼常常包含很多的小函數(shù)编曼,通過調(diào)用這些小函數(shù)豆巨,可以完成其他一組函數(shù)的“實(shí)際”工作。
類類型
- 對于一個類來說掐场,它的成員和其他任何類的成員都不是一回事往扔。
- 類的聲明:不完全類型的使用:可以定義指向這種類型的指針或引用,也可以聲明(但不能完全定義)以不完全類型作為參數(shù)或者返回類型的函數(shù)熊户。
友元
如果一個類指定了友元類萍膛,則友元類的成員函數(shù)可以訪問此類中包括非公有成員在內(nèi)的所有成員。
- 還可以另一個類的成員函數(shù)為自己的友元嚷堡。
- 如果一個類想把一組重載函數(shù)聲明稱它的友元蝗罗,需要對每一個分別聲明。
- 友元關(guān)系不存在傳遞性蝌戒。每個類負(fù)責(zé)控制自己的友元類或友元函數(shù)串塑。
類的作用域
- 一個類就是一個作用域
- 函數(shù)的返回類型通常出現(xiàn)在函數(shù)名之前,所以返回類型是在類的作用域外的北苟。
- 名字查找規(guī)則:首先名字所在快尋找聲明語句拟赊;查找外層作用;報錯粹淋。
構(gòu)造函數(shù)再探
- 如果成員是const或引用的話,必須進(jìn)行初始化瑟慈;當(dāng)成員屬于某種類類型且該類沒有定義構(gòu)造函數(shù)時桃移,也必須初始化。
- 使用構(gòu)造函數(shù)初始值:不僅僅是底層效率的問題葛碧。另有一些數(shù)據(jù)成員必須被初始化借杰。
- 成員初始化順序:構(gòu)造函數(shù)初始化列表值說明用于初始化成員的值,而不限定初始化的具體執(zhí)行順序进泼。(盡量按照順序初始化蔗衡,并且避免使用某些成員初始化其他成員)
- 委托構(gòu)造函數(shù):
- 默認(rèn)構(gòu)造函數(shù)的作用:當(dāng)對象被默認(rèn)初始化或值初始化時自動執(zhí)行默認(rèn)構(gòu)造函數(shù)
- 默認(rèn)初始化發(fā)生:
- 塊作用域內(nèi)不適用任何初始值定義一個非靜態(tài)變量或數(shù)組時。
- 一個類本身含有類類型的成員且使用合成的默認(rèn)構(gòu)造函數(shù)乳绕。
- 類類型的成員沒有在構(gòu)造函數(shù)初始值列表中顯式的初始化绞惦。
- 值初始化發(fā)生:
- 數(shù)組初始化時提供的初始值數(shù)量小于數(shù)組的大小
- 不使用初始值定義一個局部的靜態(tài)變量
- 書寫形如T()的表達(dá)式顯式的請求值初始化
- 隱式的類類型轉(zhuǎn)換:能通過一個實(shí)參調(diào)用的構(gòu)造函數(shù)定義一條從構(gòu)造函數(shù)的參數(shù)類型向類類型隱式轉(zhuǎn)換的規(guī)則:
string null_book="2132321";
item.combine(null_book);//將一個string的實(shí)參傳遞給了combine成員。
- 隱式類型轉(zhuǎn)換只能一步洋措,可以使用explicit阻止隱式類型轉(zhuǎn)換济蝉。
- 字面值常量類至少提供一個constexpr構(gòu)造函數(shù)