C++ Primer Plus 讀書筆記(第10、11章)

來源:互聯網
上載者:User

第十章 對象和類

爬山涉水終於來到了類的面前,該章開始,終於將於類進行零距離接觸了。

 

OOP設計者的思考方式

採用過程性編程方法時,首先考慮要遵循的步驟,然後考慮如何表示這些資料。OOP程式員首先考慮資料——不僅要考慮如何表示這些資料,還要考慮如何使用資料。

使用者與資料互動的方式有三種:初始化、更新和報告——這就是使用者介面。在C++中,使用者定義型別指的是實現抽象介面的類設計,一個好的介面設計應該與具體的資料關係不大,使用者無需考慮內部資料時如何運轉的,修改一個類也不要去改動介面,只需要去修改實現的細節。

 

成員變數、函數

類不同於C語言中的結構體,類中還定義了類中資料與程式員互動的操作,成員變數和函數的範圍都在類內,定義出對象後也就是無法直接存取資料或者函數,這個操作必須由一個對象發出(靜態成員除外,其由類進行限定)。對於類中的變數在其範圍為類內的基礎上,為了實現資料的封裝,成員變數又有公有和私人之分,後者不能在類外通過對象直接存取。假設有類名為NewType的類,那麼NewType::init()是函數的限定名(qualified name)而init()是全名的縮寫(非限定名,unqualified name)。

如果在類中對一個成員函數進行了定義,那麼這個函數就自動成為內嵌函式。另外如果不在類中定義的函數而想將其變為內嵌函式的話,應該在函數定義或者是函式宣告前加上inline,且應該將定義與標頭檔放在一起,這樣不會導致多個檔案對一個函數的多次定義。內嵌函式的特殊規則要求在每一個使用它們的檔案中都對其進行定義(某些開發系統包含智慧連結程式,允許將內聯定義放在一個獨立的實現檔案,經測試Dev-C++不可以)。

 

建構函式和解構函式

建構函式和解構函式能夠讓一個類變得更加的智能,我們都知道結構題能夠使用花括弧進行初始化,而一個類如果成員存在私人成員的話將不允許這種方式,因此提供一個建構函式就能夠很好的解決這個問題,而對於解構函式而言,其主要的作用就是能夠在類被銷毀的時候釋放一些對象佔用的動態記憶體,防止記憶體溢出。其實一個建構函式也可以看做是對一組資料的強制類型轉換,當提供只有一個參數的建構函式時,甚至提供了隱式的類型轉換,即NewType variable = 12; 如果提供一個接受一個int型作為函數的建構函式,左邊的運算式完全正確,這就將類與基本類型的關係拉的更近了。

如果不提供任何建構函式,那麼系統將自動調用一個什麼也不做的預設的建構函式,但是如果使用者定義了一個帶參數的建構函式,那麼系統就將不提供預設的建構函式,如果使用者需要,將要求自己提供一個可接受零參數的建構函式。解構函式是能夠顯示的調用的,但是一般不這樣做。

C++11允許使用花括弧的初始化列表類初始化類,前提是參數個數要有相應的建構函式對應。

 

常函數

成員函數的類型眾所周知都有一個this指標,但是一旦某個對象被限定為const之後那麼調用該成員函數就會出錯了。因此可以在成員函數定義的最後面加上一個const將函式宣告為常函數,定義同樣也要為加上const,這樣相應的this指標也就變成了const類型了。對於類外的普通函數是不能夠聲明為常類型的。

 

對象數組

建立對象數組一定要提供預設的建構函式,大概是因為先申請記憶體在進行初始化的緣故的吧,因此使用花括弧來初始化數組時一定會產生臨時變數(會執行解構函式)。

 

聲明類

通常,將類聲明分為兩部分組成,這兩部分通常儲存在不同的檔案中。類聲明(包括由函數原型表示的方法)應放到標頭檔中。定義成員函數的原始碼放在方法檔案中。這樣便將介面描述與實現細節分開了。

定義標頭檔時,如果標頭檔名字為My.h,那麼在開始時加上如下語句,保證不會多次編譯標頭檔:

ifndef MY_H_

define MY_H_

....

endif

 

 

 

 

 

第十一章 使用類

運算子的重載

實作類別的又一個進步是讓其與系統類別型更加靠近,換句話說C++開放了更多的許可權允許我們定義各種各樣的類型。運算子多載就是一個很重要的標誌。其格式為:

operator op (argument-list)

假設定義了<操作符,那麼對象A,B就可以直接執行A<B了,或者A.operator<(B)前者為隱式調用,而後者為顯示調用。其實也就是一個函數而已,目的是為了讓我們通過類比基本類型給這個操作符產生新的意義。對於系統重載的操作符如減號(-)和負號(-)我們也可以重載兩次,函數的特徵值也就不一樣了。

如果一個重載的函數時成員變數的話,那麼就會隱含一個參數,如果是友元的話,那麼就需要將所有的參數都寫出來了。二元操作符在隱式調用時將左邊的變數作為對象來調用,右邊的變數則是函數的參數。

 

重載限制

1.重載後的運算子必須至少有一個是使用者自訂的類型,這將防止使用者為標準類型重載運算子,不能為兩個double型重載減號運算子。

2.使用運算子時不能違反運算子原來的句法法規。例如不能將求模運算子(%)重載成使用一個運算元。

3.不能建立新的運算子。

4.不能重載以下運算子:. ,.* ,:: ,? : ,sizeof,typeid,const_cast,dynamic_cast,reinterpret_cast,static_cast。

5.以下運算子只能重載為成員函數:=,(),[],->。

一個常用的運算子多載是通過友元函數將用於重載cout<<來輸出一個對象,以及使用友元函數來實現一個常數+一個對象的情況,如果是成員函數的話系統將使用常數來調用這個重載函數,這顯然是行不通的。

 

類的自動轉換和強制類型轉換

前面說過類的建構函式看起來就像是一個類型轉換,能夠將一個基本類型轉換一個類類型。那麼通過轉換函式我們能夠將一個類類型轉換為一個基本類型。轉換函式的形式如:

operator Typename()

沒有參數和傳回值且必須是類的成員函數,對你沒有聽錯。如operator int() 定義了之後就能夠將一個對象直接賦值給int型了。

在不發生二義性的情況下,C++是允許發生隱式轉換的,例如在一個需要int型參數的地方可以直接將對象作為實參,或者需要對象作為參數的情況下,將int型作為實參。我們通常使用的string str = “hello”正是利用這種性質。可以通過在原型前加上explicit來限制隱式的轉換,只接受顯示的轉換。例如:

explicit operator int();  或者是 explicit bool operator !();

 

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.