1. 程式人生 > >C++第十章筆記

C++第十章筆記

C++通過改進C語言,使得應用更容易,最重要的OOP特性:

  • 抽象
  • 封裝和資料隱藏
  • 多型
  • 繼承
  • 程式碼的可重用性

為了把他們組合在一起,C++所做的最重要的改進是提供了類。

未開發一個類並編寫一個使用它的程式,通常,C++程式設計師將結構(類定義)放在標頭檔案中,並將實現(類方法的程式碼)放在原始碼檔案中。

為了幫助識別類,常見但不通用的約定,將類名首字母大寫。

訪問控制

類中包含private,public和protected。

類設計儘可能將共有介面與實現細節分開。公有介面表示設計的抽象元件。將實現細節放在一起並將它們與抽象分開被稱為封裝。資料的隱藏(將資料放在類的私有部分中)是一種封裝,將實現的細節隱藏在私有部分中。封裝的另一個例子是,將類函式定義和類宣告放在不同的檔案中。

資料隱藏不僅可以防止直接訪問資料,還讓開發者無需瞭解資料是如何被表示的。在對後期程式修改的時候,無需修改程式介面,這使程式維護起來更容易。

由於隱藏資料是OOP主要目標之一,因此資料項通常放在私有部分,組成類介面的成員函式放在公有部分。通常程式設計師使用私有成員函式來處理不屬於公有介面的實現細節。

其實類和結構唯一區別就是結構預設的訪問型別是public,而類為private。

實現類成員函式

除了類的描述(class部分),還需要建立類描述的第二部分:為那些由類宣告中的原型表示的成員函式提供程式碼。成員函式定義與常規函式非常相似,它們有函式頭和函式體等等。但是:

  • 定義成員函式時,使用作用域解析運算子來表示函式所屬的類
  • 類方法可以訪問類的private元件

定義在類宣告中的函式會自動生成行內函數,當然在類宣告之外定義的成員函式,也可以使用inline使之成為行內函數。

所建立的每個新的物件都有自己的儲存空間,用於儲存其內部變數和成員。但同一個類的所有物件共享同一組類方法。在OOP中,呼叫成員函式被稱為傳送訊息,因此將同樣的訊息傳送給兩個不同的物件將呼叫同一個方法,但該方法被用於兩個不同的物件。

使用類

C++的目標是使得使用類與使用基本的內建型別(int等)儘可能相同。要建立類物件,可以宣告類變數,也可以使用new對類物件分配儲存空間。可以將物件作為函式的引數和返回值,也可以將一個物件賦值給另一個。C++提供了一些工具可用於初始化物件,讓cin和cout識別物件,甚至在相似的類物件之間進行自動型別轉換。

OOP程式設計師常依照客戶/伺服器模型進行討論程式設計,客戶是使用類的程式。類宣告(包括類方法)構成了伺服器,伺服器的責任是確保伺服器根據該介面可靠並準確地執行。伺服器設計人員只能修改類設計的細節而不能修改埠。這樣對伺服器的修改不會客戶的行為造成意外的影響。

類的建構函式和解構函式

建構函式

C++提供了一個特殊的成員函式——類建構函式,專門用於構造新物件、將值付給他們的資料成員。更準確地說,C++為這些成員函式提供了名稱和使用語法,而程式設計師需要提供方法定義。

建構函式名稱與類名相同,注意好引數列表,可以過載。

注意引數名不要和private資料名相同(否則無法賦值),一般採取加字首的方式。

使用建構函式一般有兩種方式,一是顯式使用(直接呼叫建構函式,用好引數),另一種是隱式使用。

class S
{
...
}

//顯式使用
S a = S(...);

//隱式使用
s a(...);

//使用new
S *p = new S(...);

若未提供顯式初始化值會呼叫預設建構函式,但不會初始化其成員。

如果沒有自定義預設建構函式,編譯器會提供一個沒有任何操作的預設建構函式。

定義預設建構函式有兩種,一是給已有建構函式的所有引數提供預設值;二是通過函式過載定義另一個沒有引數的建構函式。

因為只能有一個預設建構函式,因此不要同時出現以上兩種方式。使用者自定義預設建構函式,一般是給所有成員初始化><。

隱式使用預設建構函式時不要使用括號,畫色添足,成宣告一個函數了。

解構函式

在建構函式建立物件後,程式負責跟蹤該物件,直到過期為止。

物件過期之後,程式將呼叫死神函式解構函式。解構函式完成清理工作。其實只有在動態記憶體上,解構函式才有更實際的意義。

比如,同new開闢的記憶體,解構函式用delete來釋放,其他情況,基本用不到解構函式= =,說的好不負責任。。。。

解構函式和建構函式差不多,只不過前面加了一個~。如果沒有手動申明一個解構函式的話,編譯器會自動加上解構函式,當然,裡面什麼都沒有,如果自定義類沒有涉及到動態記憶體的話,其實這樣也挺好。手懶的表現。

什麼時候呼叫解構函式是由編譯器決定的,一般是和棧一樣,先入後出。

C++11的初始化列表一樣可以用在物件的初始化上,不過列表裡的內容是某建構函式的引數列表。

對於類方法不會修改到被呼叫物件時,應該在函式後面新增const。const能用就用, 不只是安全!

this指標

因為在類方法中,終會遇到需要返回或者比較呼叫物件的資訊,那麼this指標應時而生,他就是一個指標,指向了當前的呼叫物件,用法和指標一樣。

物件陣列

C++目的就是使得程式設計師自定義構造的類可以和既有的資料型別使用,因此,可以用物件建立陣列等稍微高階點的資料結構。物件陣列的初始化方式有點類似結構體,但是花括號內是呼叫建構函式(顯示呼叫)或者直接什麼都不寫,預設建構函式構造。(如果是C++11的話,可以直接用初始化列表,這樣更像結構體陣列了)。

類作用域

C++自從有了類,就有了一種特殊的作用域。類內的元素,作用域只在類內,也就是說只對類內可見。這就是為什麼在定義成員函式時必須使用作用域解析運算子。

因為有了作用域,也就有了作用域為類的常量,如果想用一個const常量來控制陣列的長度,這是行不通的,因為在類中宣告的const常量要在編譯時就要分配空間,而建立類的時候,只是描述這個類而沒有分配空間,所以常量的值是未知的,則陣列的長度也是未知的。

解決方法有兩個,一個是用列舉,一個是用static const,全域性常量。

抽象資料型別(ADT)

類很適合描述ADT,公有成員函式介面提供了ADT描述的服務,類的私有部分和類方法的程式碼提供了實現,這些實現對類的客戶隱藏。


歡迎到微信裡去當吃瓜群眾