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

C++類和物件(下篇)

1. 再談建構函式

2. static成員

3.C++11的成員初始化新玩法

4. 友元

5.內部類

6. 再次理解封裝

 

1. 再談建構函式

1.1建構函式體賦值

在建立物件時,編譯器通過呼叫建構函式,給物件中各個成員變數一個合適的初始值

 

雖然上述建構函式呼叫之後,物件中已經有了一個初始值,但是不能將其稱作為類物件成員的初始化,構造數體中的語句只能將其稱作為賦初值,而不能稱作初始化因為初始化只能初始化一次,而建構函式體內可以多次賦值。

1.2初始化列表

初始化列表:以一個冒號開始,接著是一個以逗號分隔的資料成員列表,每個"成員變數"後面跟一個放在括號中的初始值或表示式。

【注意】

1. 每個成員變數在初始化列表中只能出現一次(初始化只能初始化一次)

2. 類中包含以下成員,必須放在初始化列表位置進行初始化:

引用成員變數

const成員變數

類型別成員(該類沒有預設建構函式)

 

 

 

 

3. 儘量使用初始化列表初始化,因為不管你是否使用初始化列表,對於自定義型別成員變數,一定會先使用初始化列表初始化。

4. 成員變數在類中宣告次序就是其在初始化列表中的初始化順序,與其在初始化列表中的先後次序無關

1.3 explicit關鍵字

建構函式不僅可以構造與初始化物件,對於單個引數的建構函式,還具有型別轉換的作用。

用explicit修飾建構函式將會禁止單參建構函式的隱式轉換

 

 

 

2. static成員

宣告為static的類成員稱為類的靜態成員,用static修飾的成員變數,稱之為靜態成員變數;用static修飾的成員函式,稱之為靜態成員函式。靜態的成員變數一定要在類外進行初始化

1. 靜態成員為所有類物件所共享不屬於某個具體的例項

2. 靜態成員變數必須在類外定義,定義時不新增static關鍵字

3. 類靜態成員即可用類名::靜態成員或者物件.靜態成員來訪問

4. 靜態成員函式沒有隱藏的this指標,不能訪問任何非靜態成員

5. 靜態成員和類的普通成員一樣,也有public、protected、private3種訪問級別,也可以具有返回值,const修飾符等引數

【問題】

1. 靜態成員函式可以呼叫非靜態成員函式嗎?

不可以

2. 非靜態成員函式可以呼叫類的靜態成員函式嗎?

可以

 

3.C++11的成員初始化新玩法

C++11支援非靜態成員變數在宣告時,直接初始化

 

4. 友元

友元分為:友元函式和友元類

友元提供了一種突破封裝的方式,有時提供了便利。但是友元會增加耦合度,破壞了封裝,所以友元不宜多用。

4.1 友元函式

問題:現在我們嘗試去過載operator<<,然後發現我們沒辦法將operator<<過載成成員函式。因為cout的輸出流物件和隱含的this指標在搶佔第一個引數的位置。this指標預設是第一個引數也就是左操作數了。但是實際使用中cout需要是第一個形參物件,才能正常使用。所以我們要將operator<<過載成全域性函式。但是這樣的話,又會導致類外沒辦法訪問成員,那麼這裡就需要友元來解operator>>同理。

友元函式可以直接訪問類的私有成員,它是定義在類外部的普通函式,不屬於任何類,但需要在類的內部宣告,宣告時需要加friend關鍵字。

說明:

友元函式可訪問類的私有成員,但不是類的成員函式

友元函式不能用const修飾

友元函式可以在類定義的任何地方宣告,不受類訪問限定符限制

一個函式可以是多個類的友元函式

友元函式的呼叫與普通函式的呼叫和原理相同

4.2 友元類

友元類的所有成員函式都可以是另一個類的友元函式,都可以訪問另一個類中的非公有成員。

友元關係是單向的,不具有交換性。

比如上述Time類和Date類,在Time類中宣告Date類為其友元類,那麼可以在Date類中直接訪問Time

類的私有成員變數,但想在Time類中訪問Date類中私有的成員變數則不行。

友元關係不能傳遞

如果B是A的友元,C是B的友元,則不能說明C時A的友元。

4.3 友元的優缺點

優點:提高程式的執行效率

缺點:破壞了類的封裝性和隱藏性

 

5.內部類

概念及特性

概念:如果一個類定義在另一個類的內部,這個內部類就叫做內部類。注意此時這個內部類是一個獨立的類,它不屬於外部類,更不能通過外部類的物件去呼叫內部類。外部類對內部類沒有任何優越的訪問許可權。

注意:內部類就是外部類的友元類。注意友元類的定義,內部類可以通過外部類的物件引數來訪問外部類中的所有成員。但是外部類不是內部類的友元。

特性:

1. 內部類可以定義在外部類的public、protected、private都是可以的。

2. 注意內部類可以直接訪問外部類中的static、列舉成員,不需要外部類的物件/類名。

3. sizeof(外部類)=外部類,和內部類沒有任何關係。

 

6. 再次理解封裝

C++是基於面向物件的程式,面向物件有三大特性即:封裝、繼承、多型。

C++通過類,將一個物件的屬性與行為結合在一起,使其更符合人們對於一件事物的認知,將屬於該物件的所有東西打包在一起;通過訪問限定符選擇性的將其部分功能開放出來與其他物件進行互動,而對於物件內部的一些實現細節,外部使用者不需要知道,知道了有些情況下也沒用,反而增加了使用或者維護的難度,讓整個事情複雜化。