侯捷C++八部曲:C++面向對象程序設計


1. C++編程簡介

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 2.頭文件與類的聲明

c語言的數據暴漏的太多,任何函數都能訪問,不容易維護

 

 

類分兩種,內部帶指針的和不帶指針的

 

 

 類里有指針要非常小心

 

 

 

 

 .h和.cpp是一部分,因為角色的區分,分成兩部分

自己的頭文件用雙引號,庫的用尖括號

 

 

 可以把.h拿掉,c的stdio要寫成cstdio

 

 

 

 

 

 

 

 

 

3. 構造函數

 

 

 

 private:主要作用是要封裝起來內部細節

訪問級別可以任意交錯

 創建對象的時候構造函數自動被調用。不需要返回值,因為不需要自己創建本對象。初始化列表構造函數獨有。數值設定分兩階段,用初始化和賦值,先初始化再復制。初始化列表屬於初始化,構造函數體是賦值

初始化列表的使用顯得大氣上檔次

不帶指針的類,多半不用寫析構函數

 

 

 重載是給函數改名

構造函數一個是有默認參數,一個是沒有參數,這樣不行,兩者沖突,因為編譯器不知道選哪個函數,結果不唯一

c1和c2()這兩種方式創建對象都可以

 

 4.參數傳遞與返回值

 

 

 

 

 

 函數在參數和body之間加const,代表函數不會改變對象內容

const對象調用非const方法會報錯

不改值的函數用const修飾是個好習慣

 

 盡量不要pass by value,復制浪費時間、空間。引用像指針但是更漂亮,使用更自然。引用、指針一般更快、更省空間,但和小字節數據比還是差

按值傳遞是復制參數,改了參數也不會改原值,引用為了達到這種效果,要用const在變量類型前修飾,這樣確保不會改變實參

 

 返回引用效率更高,返回值盡量是reference,有的情況不能返回ref

 

 友元比用函數拿效率高點,但是打破了封裝

 

 

 

正規寫法:

1.數據放private

2.參數盡可能以reference來傳,根據要不要改實參決定要不要帶const

3.返回值盡量以reference來傳

4.在類本體里定義的函數,不改值的加const

5.構造函數用初始化列表初始化

返回reference:返回的是一個本來就有的東西,不會有錯。local對象就不能做為reference返回

reference主要用在傳遞東西上

 

5. 操作符重載與臨時對象

 

 編譯器自動把c2地址傳進來當成this,this是函數的隱藏參數

 

返回的是引用,接收端怎么接收不用在乎,用引用和value接收都可以,方便書寫,只是效率有差別。傳回指針就不行了,必須用指針接收,無法連着用。如果不加引用返回一個已存在對象,相應的會生成一個臨時對象,構造、拷貝、析構分別來一次(造一個對象,要不用來常量引用要不用來拷貝,對左值修改影響不了原值,引用直接編譯報錯;NRVO可以優化不生成對象,直接走拷貝,效率一致,但NRVO可能失效),引用則是指針賦值或者拷貝一次。返回臨時對象少復制一次只有一次構造,有編譯器優化(RVO)

 

 

 

 重載只有一個能符合,多了編譯器報錯

多個參數,順序不定,用全局的容易掌控

參數沒有this pointer

 

臨時對象,沒有名字,聲明在下一行已經結束了 

 

運算符 全局重載,靠參數個數確定函數名.只有一個參數放對象左邊的,可以設計為全局函數也可以設計為類函數,運算符重載函數的結合性和默認的是一樣的

 

 

 

 

 

有些類不能修改,要用全局運算符重載其運算符

不是自己寫的,參數別加const

 

 

6.復習Complex類的實現過程

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

7. 三大函數:拷貝構造,拷貝復制,析構

 

 

 

 

 拷貝構造與拷貝賦值區別:一個是構造初始化一個是賦值,拷貝構造的對象之前不存在,所以與賦值構造處理不同,不用清理以前的垃圾

默認的是按bit復制,沒有指針、引用就夠用

 

 

 

 

 s1()也會調用構造函數

 

 

 淺拷貝,內存泄漏和數據別名

 

拷貝構造函數只是復制,不想改變外面對象,所以要const參數

 

 

 

 判斷是否是自己,清空已有數據,拷貝新數據。給已有對象重新賦值

 

 

 

 

 

 

 

 沒有自我賦值檢測,一是慢,二是產生懸垂指針

 

 

 

8,堆、棧與內存管理

 

 對象的內存,要不位於棧區要不位於堆區

 

 

 析構函數自動被調用

 

 

 

global對象構造函數早在main執行前就被調用

類中的靜態變量與全局變量相同。它的構造函數將在進入 main 函數之前被調用。

  • 結論(適用於 g++、Windows 環境):
  • 全局變量 類中的靜態成員 : 在輸入之前調用構造函數 功能 (1) .
  • 局部靜態變量 : 構造函數僅在第一次執行到達其聲明時調用。
  • 局部靜態變量為 POD 類型 , 那么在輸入 之前也是初始化的主 功能 (1) .
    POD 類型示例:static int number = 10;

(1) :正確的狀態應該是:“在調用來自同一翻譯單元的任何函數之前”。但是,為了簡單,如下例所示,它是主要功能。

 

 

 

 內存泄漏:沒機會再delete堆上對象了,失去了控制

 

"operator new",函數名就叫這個

 

 刪除兩塊堆上的內存

 

 上下紅色cookie用於記錄整塊大小,方便回收

最后一位,0x41, 1用來表示已分配不可用,0用來表示可用未分配。最后一位可以借位是因為地址一定是16的倍數,所以最后一位必為零

 

 

 數組個數排在數據前面

 

這里指針對象、數組指針還是指向對象內存地址的,而不是cookie等附加數據,相應的delete函數會自己去找

 寫不寫中括號不影響內存刪除,但是影響析構函數調用,內存泄漏的是數據里的指針指向的堆內存。如果是復數類而不是字符串,加不加中括號都行

 

9. 復習String類的實現過程

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

10.  擴展補充:類模板,函數模板,及其他

 

 

 靜態成員數據是類只有一份,靜態函數只能操作靜態對象成員

 

靜態成員數據要在類外面初始化,不然編不過。

這也叫靜態成員的定義,定義會開內存空間。類里面的是聲明而已,因為靜態成員脫離於對象,是屬於類的

 

 

 

 

 懶漢與餓漢模式區別

 

 

 

 

 

 

 template里typename和class相通

類模板明確指出type,函數模板是根據參數自行推導

 

 

 namespace解決同名問題

 

 

 

 

11. 組合與繼承

 面向對象編程:類和類之間產生關系

 

 

 

 

 黑色菱形代表里面有東西

 

 

 

 

 編譯器幫助調用部件的構造、析構。

各自管各自的構造和析構即可,編譯器全做好了

如果調用默認的構造、析構不合適,就自己在初始化列表上調用組件的構造函數

 

 

 白色菱形是委托,用指針指向,有些虛

 二者壽命不一致

pImpl模式:左邊是接口,真正的實現在委托那里,方便實現變動、切換,這樣就具有了彈性

這種手法也叫做編譯防火牆

還有就是cow技術,改的時候才真正開辟新內存進行拷貝,不然就是復制一個指針

 

 白色三角形代表繼承

 

 基類析構不是virtual,可能發生只調用基類析構不調用子類析構

 

12. 虛函數與多態

繼承主要作用是要搭配虛函數,內存布局倒是其次

 函數的繼承不應該從內存的角度理解,函數的繼承繼承的是調用權

 子類可以調用父類的函數

 

形狀很抽象,沒什么東西就直接是形狀,所以要定義有純虛函數

虛函數:希望子類來做,父類不做或者做的默認實現比較簡單

 

 

 

 關鍵動作延緩到子類去做,叫做template method

 本質是虛函數通過vptr來調用,看是this指針是哪個對象就調到哪個函數

 

 

 

 既有基類又有Component,先調用基類構造函數

 

13. 委托相關設計

 

 

 

 

組合模式:容器可以容納單體及容器

C++容器里要放指針,因為必須一樣大小,放對象可能基類、子類不一樣大

 

 

 原型模式:應對未來之對象,要求其繼承已有對象,用靜態對象創建自己,構造函數里將其add進框架,框架提供虛函數,子類實現copy子類自己創造的東西

LSAT:帶下划線,是靜態的,所以類自己創造了自己

類圖先寫名字再寫類型

-代表private,#代表protected

通過存儲的指針調用相應類的clone方法,clone里調用protected構造函數防止調用私有的構造函數又注冊一次

框架應有之意:實現框架預置的方法,框架先寫好了又要讓他知道自己

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM