1. 程式人生 > >C++類和物件(上篇)

C++類和物件(上篇)

類與物件(上)

1. 類與物件的初步認知

2. 類的引入

3. 類的定義

4. 類的作用域

5. 類的例項化

6. 類的訪問限定符及封裝

7. 類的物件大小的計算

8. 類成員函式的this指標

1. 類與物件的初步認知

C語言是面向過程的,關注的是過程,分析出求解問題的步驟,通過函式呼叫逐步解決問題。

C++是基於面向物件的,關注的是物件,將一件事情拆分成不同的物件,靠物件之間的互動完成。

2.類的引入

C語言中,結構體中只能定義變數,在C++中,結構體內不僅可以定義變數,也可以定義函式。

上面結構體的定義,在C++中更喜歡用class來代替。

3.類的定義

class為定義類的關鍵字ClassName為類的名字{}中為類的主體,注意類定義結束時後面分號。

類中的元素稱為類的成員類中的資料稱為類的屬性或者成員變數; 類中的函式稱為類的方法或者成員函式

類的兩種定義方式:

1. 宣告和定義全部放在類體中

【注意】:成員函式如果在類中定義,編譯器可能會將其當成行內函數處理。

2. 宣告放在.h檔案中,類的定義放在.cpp檔案中

一般情況下,更期望採用第二種方式。

4.類的訪問限定符及封裝

4.1 封裝

【面試題】 面向物件的大特性封裝、繼承、多型。

在類和物件階段,我們只研究類的封裝特性,那什麼是封裝呢?

封裝:將資料和操作資料的方法進行有機結合,隱藏物件的屬性和實現細節,僅對外公開介面來和物件進行互動。

4.2 訪問限定符

C++實現封裝的方式:用類將物件的屬性與方法結合在一塊,讓物件更加完善,通過訪問許可權選擇性的將其介面提供給外部的使用者使用。

【訪問限定符說明】

1. public修飾的成員在類外可以直接被訪問

2. protected和private修飾的成員在類外不能直接被訪問(此處protected和private是類似的)

3. 訪問許可權作用域從該訪問限定符出現的位置開始直到下一個訪問限定符出現時為止

4. class的預設訪問許可權為private,struct為public(因為struct要相容C)

注意:訪問限定符只在編譯時有用,當資料對映到記憶體後,沒有任何訪問限定符上的區別

【面試題】

1. 如何在類外訪問一個類中私有的成員變數?

(1)通過公共函式為私有成員賦值

(2)利用指標訪問私有資料成員

(3)利用函式訪問私有資料成員

2. C語言和C++中struct的區別?C++中struct和class的區別?

1.C語言是結構體,C++是結構體和類

2.class的預設訪問許可權為private,struct為public

5.類的作用域

類定義了一個新的作用域,類的所有成員都在類的作用域中。在類體外定義成員,需要使用 :: 作用域解析符指明成員屬於哪個類域。

問題:在使用一個變數前,必須先要對變數進行宣告,在上述Test類中,a成員變數在SetA函式之後,為什麼編譯器沒有報錯? 【注意】

1. 儘量避免成員函式的引數與成員變數同名

2. 成員變數在類中具有全域性作用域屬性

6.類的例項化

用類型別建立物件的過程,稱為類的例項化

1. 類只是一個模型一樣的東西,限定了類有哪些成員,定義出一個類並沒有分配實際的記憶體空間來儲存它

2. 一個類可以例項化出多個物件,例項化出的物件佔用實際的物理空間,儲存類成員變數

3. 做個比方。類例項化出物件就像現實中使用建築設計圖建造出房子,類就像是設計圖,只設計出需要什麼東西,但是並沒有實體的建築存在,同樣類也只是一個設計,例項化出的物件才能實際儲存資料,佔用物理空間

7.類物件模型

7.1如何計算類物件大小

成員變數是獨立的,成員函式是共享的

7.2 類物件的儲存方式猜測

1.物件中包含類的各個成員

缺陷:每個物件中成員變數是不同的,但是呼叫同一份函式,如果按照此種方式儲存,當一個類建立多個物件時,每個物件中都會儲存一份程式碼,相同程式碼儲存多次,浪費空間

2.函式單獨存放一份,物件中給一個指標指向存放成員函式表的首地址

缺陷:物件中還是多了一個指標。

3.只儲存成員變數,成員函式存放在公共的程式碼段

結論:一個類的大小,實際就是該類中”成員變數”之和,當然也要進行記憶體對齊,注意空類的大小

空類比較特殊,編譯器給了空類一個位元組來唯一標識這個類。那類物件模型即:類中各個成員變數在記憶體中的部分形式,可以表示為:

7.3 結構體記憶體對齊規則

1. 第一個成員在與結構體偏移量為0的地址處。

2. 其他成員變數要對齊到某個數字(對齊數)的整數倍的地址處。

注意:對齊數 = 編譯器預設的一個對齊數 與 該成員大小的較小值。

VS中預設的對齊數為8,gcc中的對齊數為4

3. 結構體總大小為:最大對齊數(所有變數型別最大者與預設對齊引數取最小)的整數倍。

4. 如果嵌套了結構體的情況,巢狀的結構體對齊到自己的最大對齊數的整數倍處,結構體的整體大小就是所有最大對齊數(含巢狀結構體的對齊數)的整數倍。

8.this指標

8.1this指標的引出

對於上述類,有這樣的一個問題:

Date類中有SetDate與Display兩個成員函式,函式體中沒有關於不同物件的區分,那當s1呼叫SetDate函式時,該函式是如何知道應該設定s1物件,而不是設定s2物件呢?

C++中通過引入this指標解決該問題,即:C++編譯器給每個“成員函式“增加了一個隱藏的指標引數,讓該指標指向當前物件(函式執行時呼叫該函式的物件),在函式體中所有成員變數的操作,都是通過該指標去訪問。只不過所有的操作對使用者是透明的,即使用者不需要來傳遞,編譯器自動完成。

8.2 this指標的特性

1. this指標的型別:類型別* const

2. 只能在“成員函式”的內部使用

3. 時時刻刻指向當前物件,不屬於物件的一部分,不會影響sizeof的結果

4. this指標是成員函式第一個隱含的指標形參,一般情況由編譯器通過ecx暫存器自動傳遞,不需要使用者傳遞

【面試題】

1. this指標存在哪裡?

this存在棧上,windows下通過exc暫存器自動傳遞。

2. this指標可以為空嗎?

可以為空