boolan物件導向程式設計 第一周筆記

2021-08-03 21:17:07 字數 2934 閱讀 8130

標頭檔案與類的宣告

標頭檔案為防止重複宣告,標頭檔案的防衛式宣告格式如下:

#ifndef _complex_  

#define _complex_  

...//一些宣告語句  

#endif  

標頭檔案的基本布局格式如下:

#ifndef _complex_  

#define _complex_  

#include

class ostream;  

class complex;   //前置宣告  

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

class complex  //類-宣告  

;  complex::function //類-定義  

#endif //_complex_  

思考與拓展:

為什麼標頭檔案要有防衛式格式?這個要從編譯器如何對頭檔案進行預處理說起:

編譯器將處理掉所有注釋,以空格代替;

刪除#define,展開所有巨集定義;

處理條件編譯指令#if、#ifdef、#elif、#else、#endif;

處理#include,展開被包含的標頭檔案(直接將標頭檔案複製進檔案)

保留編譯器需要使用的#progma指令等等。

如果有多份標頭檔案均不進行防衛式宣告,均包含了類似這種內容很多的標頭檔案,經過預處理以後的檔案,即便自己只寫了一行**cout,它包含的**量將是何其的龐大。這還不是最關鍵的問題,關鍵是標頭檔案中定義了乙個變數,那麼多次包含該標頭檔案之後,就會產生重複定義的問題。

是不是只有這一種防衛式宣告呢?除了課程中出現的這種,還有另外一種格式:

[cpp] view plain copy print?

#pragma once  

...//一些宣告語句  

兩者的差別:

#ifndef的方式依賴於巨集名字不能衝突,這不光可以保證同乙個檔案不會被包含多次,也能保證內容完全相同的兩個檔案不會被不小心同時包含。當然,缺點就是如果不同標頭檔案的巨集名不小心「撞車」,可能就會導致標頭檔案明明存在,編譯器卻硬說找不到宣告的狀況

#pragma once則由編譯器提供保證:同乙個檔案不會被包含多次。注意這裡所說的「同乙個檔案」是指物理上的乙個檔案,而不是指內容相同的兩個檔案。帶來的好處是,你不必再費勁想個巨集名了,當然也就不會出現巨集名碰撞引發的奇怪問題。對應的缺點就是如果某個標頭檔案有多份拷貝,本方法不能保證他們不被重複包含。當然,相比巨集名碰撞引發的「找不到宣告」的問題,重複包含更容易被發現並修正。

方式一由語言支援所以移植性好,方式二 可以避免名字衝突。

到底選哪一種呢,這是個相容性和效率的問題。

3.建構函式

初始化列表

乙個變數的數值設定有兩個階段:乙個是初始化,乙個是後面的賦值操作,而初始化列表就是在初始階段。如果放入大括號裡面來做,結果相同,但相當於放棄了初始化,效率會差一些。

建構函式放在private 

把建構函式放在private是不能被構造的,不能被外界呼叫。因為建立乙個物件會呼叫建構函式,而private裡的函式是不能被外界呼叫的,因此事不可以的。但確實有一種需求是放在裡面:單例模式(singleton)

[cpp] view plain copy print?

class a  

private:  

a();  

a(const a& rhs);  

...   

};  

a& a::getinstance()  

使用:[cpp] view plain copy print?

a::getinstance().setup();  

對不改變資料內容,只是取出來的,加const

4.引數傳遞及返回值

引數傳遞:pass by value or pass by reference(to const) 

可看出有三種情況,先看pass by value:傳遞value,就是複製資料整包的傳過去,把複製的引數壓到函式的棧裡面去。很顯然效率低,因此盡量不要pass by value,而應該盡量使用pass by reference。(c語言中有傳遞指標的),其實引用在底層就是指標實現的,所以說pass by reference傳遞快,因此盡量使用引用傳遞。而如果傳遞的資料不希望被更改就使用pass reference to const。

pointer引數和reference引數的重要差異:傳入的pointer可能為0,因此必須得先檢查確定其值是否為0,而reference則必定會代表某個物件,所以不須做此檢查

返回值傳遞return by value vs return by reference(to const)

c++的效率高,在每乙個影響效率的小節上應該注意,返回值的傳遞也盡量return by reference(當然在可以的情況下),有些情況是不可以的,下面看這種情況。

乙個函式的操作結果放在什麼位置?如果必須建立乙個位置供他放,那返回的就是新的local物件,這時候不能return by reference,因為local 變數,函式一結束就已經死亡了,這樣就會出錯。若放在函式某個位置,那就可以傳遞reference。

5.操作符過載

操作符過載-成員函式

所有的成員函式函式都帶著乙個隱藏的引數this指標。

temp object臨時物件

typename()就是要建立臨時物件,對於臨時物件的生命週期:下一行就結束了。建立臨時物件的用法在建立stl中很常見。 

注意對於這些臨時物件絕不可return by reference。因為它們是local object。

小結:標頭檔案防衛式宣告;

建構函式的初始化問題;

資料盡量放在private裡面;

傳遞引數:盡量用 pass by reference;

傳遞返回值:若不是local object,盡量用return by reference;

若是函式呼叫不用改變引數,則加上const;

C 物件導向高階程式設計(下) 第一周

你現在設計乙個物件 class a,它可不可以被轉為另外一種型別,這就是一種轉換。或者是,另外一種型別可不可以轉為a。乙個是轉出去,乙個是轉進來,這兩個方向,我們都要談。現在首先談的是轉出去 1 轉化函式不可以有引數。轉換型別而已,那有什麼引數可言。2 轉化函式沒有返回型別,返回型別就是operat...

C 物件導向高階程式設計(下) 第一周

你現在設計乙個物件 class a,它可不可以被轉為另外一種型別,這就是一種轉換。或者是,另外一種型別可不可以轉為a。乙個是轉出去,乙個是轉進來,這兩個方向,我們都要談。現在首先談的是轉出去 1 轉化函式不可以有引數。轉換型別而已,那有什麼引數可言。2 轉化函式沒有返回型別,返回型別就是operat...

第一周程式設計總結

7 2 求最大值及其下標 20 分 本題要求編寫程式,找出給定的n個數中的最大值及其對應的最小下標 下標從0開始 輸入在第一行中給出乙個正整數n 1 在一行中輸出最大值及最大值的最小下標,中間用乙個空格分開。本題一次性通過,沒什麼問題。7 1 查詢整數 10 分 本題要求從輸入的n個整數中查詢給定的...