讀書筆記 Effective C

2022-03-01 14:50:30 字數 2441 閱讀 6029

乙個常見的面試題就是問「乙個空類佔幾個位元組」,想當然的是0個位元組,但事實上類要區分不同的物件,比如:

1

emptyclass obj1;

2 emptyclass obj2;

即便是空類,也要能識別obj1和obj2的不同,所以空類仍然要佔位元組數,一般佔乙個位元組。

還有乙個針對空類的問題是「乙個空類裡面有什麼」,就是想問編譯器為這個空類自動生成了哪些成員函式。

很容易想到的是生成了預設的建構函式和析構函式,事實上還有拷貝建構函式和賦值運算子,所以,總共生成了四個成員函式。具體地說,就是你表面上寫了

1

class emptyclass

2;

但實際編譯器為你加了四個成員函式,所以看起來像這樣:

1

class emtpyclass27

8910//

析構函式

11 ~emptyclass(){}

1213

1415

//拷貝建構函式

16 emptyclass(const emptyclass&obj)

1720

2122

23//

賦值運算子過載

24 emptyclass& operator= (const emptyclass&obj)

2528

29};

3031

拷貝建構函式和賦值運算子的函式體內容由成員變數決定,假設有成員變數var1和var2,那麼拷貝建構函式和賦值運演算法的函式體像這樣:

1 emptyclass(const emptyclass&obj):var1(obj.var1), var2(obj.var2){}23

45 emptyclass& operator= (const emptyclass&obj)

6

賦值運算子要返回自身*this,是因為考慮到可以出現連等的情況,比如obj1 = obj2 = obj3,另外,這裡都使用了自身類的引用,即emptyclass&,這裡的引用是必須要加的,這是因為:

(1) 引用修飾形參時,可以避免實參對形參的拷貝,一方面可以節省空間和時間資源,更為重要的是若實參對形參拷貝了,又會呼叫一次拷貝建構函式,這樣拷貝建構函式就會一遍又一遍的被呼叫,造成無窮遞迴。

(2) 引用修飾返回值時,可以使返回的物件原地修改。比如(a=b) ++,這樣返回的a物件還可以進行自增操作,如果不加引用,則因為生成的是原物件的拷貝,所以這樣的自增操作並不使a本體自增。

對初學者而言,還要注意區分什麼時候呼叫的是賦值運算子,什麼時候呼叫的是拷貝建構函式。比如:

emptyclass a(b); //

呼叫的是拷貝建構函式

emptyclass a = b; //

呼叫的是拷貝建構函式

1

emptyclass a;

2 a = b; //

呼叫的是賦值運算子

這裡注意一下第二個和第三個例子,同樣是等號,但卻呼叫了不同的成員函式,重要的區別就要看是不是在這句話中新產生乙個物件,第二個例子新產生乙個物件,所以呼叫的是拷貝構造,第三個例子a在「=」前已經誕生了,所以呼叫的是賦值運算子。

本書中還講到了乙個特殊的情況,就是成員變數是const的,或者是引用,比如:

1

class

sampleclass

2;

這時候編譯器會報錯,告訴你無法提供合適的建構函式,因為對於const變數以及reference,需要在宣告的時候初始化,而編譯器提供的預設建構函式顯然無法做到這點。可以改成下面這樣:

1

class

sampleclass29

10 };

編譯器不會報錯了,但是如果像這樣:

1

sampleclass obj1;

2sampleclass obj2;

3 obj2 = obj1;

編譯器會提示「operator =」函式在「sampleclass」中不可用,這說明編譯器同樣沒有為sampleclass生成賦值運算子,因為var1和var2在初始化後,值就不能再改變了。但:

1

sampleclass obj1;

2 sampleclass obj2(obj1);

卻是可以編譯通過的,這是因為編譯器可以生成預設的拷貝建構函式:

sampleclass(const sampleclass& s): var1(s.var1), var2(s.var2){}

這種生成方式並不會破壞const和reference的特性。

綜上,編譯器總是盡量地去生成這四個成員函式,但如果成員變數出現了const和reference,則編譯器會拒絕生成預設的建構函式和賦值運算子過載函式。

《effective C 》讀書筆記

1,c 關鍵字explicit c 中,乙個引數的 建構函式 或者除了第乙個引數外其餘引數都有預設值的多參建構函式 承擔了兩個角色。1 是個 構造器,2 是個預設且隱含的型別轉換操作符 所以,有時候在我們寫下如 aaa 這樣的 且恰好 的型別正好是aaa單引數構造器的引數型別,這時候 編譯器就自動呼...

Effective C 讀書筆記

一 讓自己習慣c 1 條款01 視c 為聯邦語言 c 的組成可分為四部分 1.c c 仍然以c語言為基礎。區塊 語句 預處理 內建資料型別 陣列 指標等都來自c。2.object oriented c c with classes所訴說的 classes 包括構造和析構 封裝 繼承 多型 virtu...

讀書筆記 Effective C

部分條款過於深奧,部分條款已了然於心,僅記錄當下所識所學 對於常量巨集定義,最好用const代替 define 對於函式巨集定義,最好用inline代替 define include ifdef ifndef仍被需要 內建物件記得手動初始化 使用成員初始列替換賦值操作 以local static替換...