天天看點

C++面向對象進階程式設計(上) 第一周 侯捷頭檔案與類聲明

頭檔案與類聲明

頭檔案中的防衛式聲明

#ifndef _FILENAME_
#define _FILENAME_
//...
#endif           

擴充:為什麼要添加防衛式聲明(防止由于同一個頭檔案被包含多次,而導緻了重複定義。)

https://www.cnblogs.com/xyq10612/p/5910933.html

頭檔案的布局

#ifndef __COMPLEX__
#define __COMPLEX__

#include<cmath>

//前置聲明
class ostream;
class complex;

complex&
   _doapl(complex * ths, const complex);


//類聲明
class complex {

};

//類定義
complex::function....

#endif
           

模闆簡介

C++面向對象進階程式設計(上) 第一周 侯捷頭檔案與類聲明

構造函數

内聯函數

1、你的函數在你的類本體裡面定義,那麼你就是一個inline。

2、如果你的函數太複雜,就沒有辦法inline

C++面向對象進階程式設計(上) 第一周 侯捷頭檔案與類聲明

3、即使你把函數寫在了class裡面,最後的結果是否inline,是由編譯器去決定的。

4、不在類裡面定義的函數,你也可以把他inline,如上圖(2-2)。寫了一句:inline double

通路界别(access level)

1、什麼東西應該是private的呢?   應該是資料的部分,因為我們的資料應該是封裝起來的,不要被外界任意看到。

C++面向對象進階程式設計(上) 第一周 侯捷頭檔案與類聲明

2、public 和private是可以交錯出現的。也就是說,你的class body很大,你可以先些一段public,之後寫一段private,後面想到了什麼,可以再插一段public,之後還可以在寫private

構造函數(constructor)

1、如果你想要建立一個對象,有一個函數會被自動的調用起來,這個函數就是構造函數。

2、下圖用動态的方法去建立一個對象,得到的會是一個指針。

C++面向對象進階程式設計(上) 第一周 侯捷頭檔案與類聲明

3、構造函數的函數名和類名相同

4、他可以有參數,參數可以有預設值(default argument)

【有了預設值,當你建立對象的時候,如果沒有指明參數值,則用預設值】

5、他沒有傳回值類型

C++面向對象進階程式設計(上) 第一周 侯捷頭檔案與類聲明

6、初值列——隻有構造函數享有這個功能

C++面向對象進階程式設計(上) 第一周 侯捷頭檔案與類聲明

上圖把r設到re中去,把i設定到im中去

7、不寫初始列就不是練家子的原因:一個變量,它的數值的設定有兩個階段,一個是初始化,一個是指派。如果你不寫初始列,直接在函數體裡面指派,證明你放棄了初始化的階段,這樣的話指派的時間點會晚一些,效率會差一些。

C++面向對象進階程式設計(上) 第一周 侯捷頭檔案與類聲明

8、你不可能在你的程式裡面去調用構造函數,你隻可能去建立對象。建立對象時,構造函數會自然而然被調用起來。

9、不帶指針的類,大部分不用寫析構函數。

構造函數可以有很多個-----重載(overloading)

C++面向對象進階程式設計(上) 第一周 侯捷頭檔案與類聲明

兩個構造函數real的名稱相同,但是編譯器是可以厘清誰是誰的,是以可以重載。(編譯器通過函數名,裡面的參數名,參數類型等一系列的資訊來區分同名的構造函數)

1、在c++中,同名(其實對于編譯器來說是不同名的)的函數可以存在。

2、函數重載常常發生在構造函數中。

3、由于目前擁有的構造函數已經有預設值了,你還是可以去重載寫出其他的構造函數,但是你新寫的構造函數沒有預設值就不行,會引起沖突。如下圖,2就不會被調用

C++面向對象進階程式設計(上) 第一周 侯捷頭檔案與類聲明

參數傳遞與傳回值

把構造函數(ctors)放在private區域裡

當不允許被外界建立對象的時候,把構造函數放在private裡面。那這個類有什麼用?

下圖是一個有名的設計模式singleton就用到了把ctors放在prvate裡

C++面向對象進階程式設計(上) 第一周 侯捷頭檔案與類聲明

擴充:懶漢模式he餓漢模式

https://blog.csdn.net/hj605635529/article/details/70172842

常量成員函數(在函數()的後面{}的前面,寫一個const )

該函數的意思是不會改變傳入的資料的内容,如下圖:

C++面向對象進階程式設計(上) 第一周 侯捷頭檔案與類聲明
C++面向對象進階程式設計(上) 第一周 侯捷頭檔案與類聲明

上述類中,如果函數real 和函數imag沒有加上const,則使用者希望不改變傳入值時,給自己的調用前面加上了const程式會報錯,因為類中的函數沒加上const代表你傳入的值可以改變。

是以,類中的real函數和imag函數需要加上const。此例說明,在設計函數的時候,要充分考慮各種情況。

const出現在對象或者變量的前面,說明我的對象或者變量是不可改動的。e.g 

C++面向對象進階程式設計(上) 第一周 侯捷頭檔案與類聲明

參數傳遞:pass by value vs pass by reference

1、Pass by value 是把資料整包的傳過去,壓入到棧中,是以盡量不要pass by value

2、引用在底層就相當于一個指針,是以傳遞引用就相當于傳遞指針那麼的快

3、傳引用 to const 可以保證傳遞速度快,而且你不會改變我傳入的值。如下圖:

C++面向對象進階程式設計(上) 第一周 侯捷頭檔案與類聲明

傳回值傳遞:return by value  vs return by reference

C++面向對象進階程式設計(上) 第一周 侯捷頭檔案與類聲明

friend友元

可以直接拿你private的資料

C++面向對象進階程式設計(上) 第一周 侯捷頭檔案與類聲明

同一個class内的各個對象互為友元(friend)

C++面向對象進階程式設計(上) 第一周 侯捷頭檔案與類聲明

直接擷取了私有資料

對于類,老師會特别注意什麼地方呢?

1、資料放在private裡面

2、參數和傳回值盡可能使用reference來傳

3、類中的函數,應該加const的就要加,否則使用者在使用的時候會報錯。

4、構造函數的初始列要盡量去用。

什麼情況下不能return by reference

函數運作結束的時候,函數内建立的變量會被銷毀。如下圖,就不能return 參數三的reference

C++面向對象進階程式設計(上) 第一周 侯捷頭檔案與類聲明

操作符重載與臨時對象

操作符重載-1,成員函數,this

1、在C++中,操作符就是一種函數,是可以讓你重新定義的。

2、所有的成員函數一定帶着一個隐藏的參數this,誰調用我的成員函數,這個隐藏的this就指向它(比如下圖中的this)

C++面向對象進階程式設計(上) 第一周 侯捷頭檔案與類聲明

return by reference 文法分析

  1. 如果用reference來傳的話,傳遞者無需知道接受者是以什麼形式接收(也許是by value,也許是by reference)
C++面向對象進階程式設計(上) 第一周 侯捷頭檔案與類聲明
C++面向對象進階程式設計(上) 第一周 侯捷頭檔案與類聲明

(操作符要考慮使用者的連串使用情況

C++面向對象進階程式設計(上) 第一周 侯捷頭檔案與類聲明

全域函數(不是在class中聲明的函數,如下圖所示)

C++面向對象進階程式設計(上) 第一周 侯捷頭檔案與類聲明

操作符重載-2 非成員函數 無this

temp object臨時對象  typename ();(例如. int ();)

C++面向對象進階程式設計(上) 第一周 侯捷頭檔案與類聲明

因為complex是函數中建立出來的,是以你的傳回值不是by reference,而是by value。

臨時對象:臨時想要的東西,我不想給你名稱,他的生命到下一行就結束了。

編譯器如何區分加減和取正負呢?  ---看參數就知道了,隻有一個參數的,肯定是取正負

C++面向對象進階程式設計(上) 第一周 侯捷頭檔案與類聲明

操作符重載 非成員函數

C++面向對象進階程式設計(上) 第一周 侯捷頭檔案與類聲明

“<<” out put operator 不要想把這種操作符寫成一個成員函數

(操作符有兩種寫法,一種是成員函數的寫法,一種是非成員函數的寫法),這個操作符隻能考慮全局的那種寫法

因為如果你傳回的是引用,那麼你就是要把傳回值指派給”<<”左邊的”cout”,可是”cout”是标準庫的東西,你不可能指派給他,是以,對于”<<”操作符,無法寫成成員函數,其他的操作符寫成成員函數或者非成員函數都是可以的,但是單單這個不行。

函數的傳回值類型沒有用void,是因為有可能使用者會使用連續的輸出,如下圖

C++面向對象進階程式設計(上) 第一周 侯捷頭檔案與類聲明
C++面向對象進階程式設計(上) 第一周 侯捷頭檔案與類聲明

繼續閱讀