Effective C 讀書筆記

2021-10-23 09:14:28 字數 2929 閱讀 5475

.h class ***

.cpp const int ***::num;

#include => #include

malloc, free => new, delete

new x,delete x.

new x[100],delete x

void ***x(){}

set_new_handler(***x)設定new記憶體不足時的響應函式

set_new_handler(0) 清空自己設定的響應函式

寫operator new時必須返回乙個合法位址或丟擲異常,如果發生繼承,則需判斷如果大小不正確之記憶體請求(子類繼承而來的operator),要呼叫::operator new ::operator delete

如果類定義了operator new,它會遮掩掉全域性operator new。

通常oerator new返回記憶體之前會記錄記憶體大小等資訊,供operator delete使用,若需自己定義operator new(如採用記憶體池方式),需相應operator delete

若沒有提供,則內部動態配置的記憶體會有洩露、重複釋放的問題。

盡量用member initialization list,const 成員和 引用成員 只能在member initialization list中初始化。

當企圖以乙個base class ptr刪除乙個derived class obj時,而此base class有乙個nonvirtual destructor,結果是未定義的。

只有在類作為基類時,析構才需要為virtual

否則a=b=c=1這樣的就不支援了

在operator=和copy ctor中需要呼叫基類相應函式,確保基類部分也正確設定

虛函式必須是member function

operator>> operator<< 不可以為member funcion,可以為non-member,如果還需訪問non-public member則讓其為friend

如果需要在最左端引數上實施型別轉換,則為non-member,如果還需要訪問non-pulibc member則讓其為friend

// 2* obj, obj* 2需要下面函式支援

const class operator*(const class& l, const class& r){}

上述之外的都為member function

[const] char* [const] ptr,看const緊挨著哪個就是哪個為const

返回值為const時能防止a*b=c這種無意義的**。

const member funcion是為了指明哪個成員函式可由const物件呼叫

// 此種函式若返回引用將有各種問題,傳值較好

const class operator*(const class& l, const class& r){}

如果有合理預設值,且演算法只一種時用預設引數較好。

若無合理預設值(求平均值)時,則使用過載較好。及建構函式這種需要完成一項特別任務,但採用演算法需要視輸入而定時,也用過載

void f(int);void f(string* p);  f(0);f(null);會正確工作嗎?最好不要如此過載
遇到有ambiguity情況,編譯器會報錯,必須指明呼叫目標。函式的「訪問限制」(public protect private)改變,不能改變多繼承而來的members的ambiguity狀態。

將相應函式宣告為private,且不給任何定義。

模組使用namespace的必要

內部資料的指標和引用,不要讓函式傳回,否則外部可以使用指標、引用不受控制的修改資料。

成員函式若要返回低訪問層級成員(如public函式返回private成員)時,請確保是返回const

前者引用無效物件,後者有記憶體洩露風險

需要時才定義,可以降低程式消耗。免除無意義的物件構造、賦值。

inline會展開在每一處呼叫之處,**會膨脹,適合短小函式。

inline非強制性,編譯器會自行決斷,一般內含迴圈或遞迴呼叫的,或虛函式都會被拒絕inline

handle class: classx 內含乙個 classimplx的指標,所有操作都**至pimpl。

protocol class:純虛基類,子類實現基類所有介面

可以降低編譯信賴狀態

子類要滿足黎克特制代換原則,如駝鳥是鳥但不能飛,正方形之於矩形

否則derived d; base* pb= &d;derived* pd= &d; pb->fun();與pd->fun();可能不同。

預設引數值是靜態繫結,而虛函式是動態繫結shape* p = new circle(); p->draw();此函式的預設引數是由shape型別決定的

如果需要進行判斷指向內容為哪個子類,再執行什麼操作時,用虛函式來實現。

如果避免不了,至少要用上dynamic_cast

layering也叫composition,如person中包含address phonenumber等,邏輯上不適用繼承的情況,考慮用has-a來實現,如果有虛函式要重定義需要用private繼承。

如果型別t會影響class的行為時,用繼承,否則用模板。

private繼承時,父類中public proctected成員都在子類中變成private,編譯器不會自動將乙個子類轉換為父類。而僅有繼承時會有這種自動轉換。private繼承僅為實現上的一種方法,而在軟體設計層面無意義。

盡量避免虛基類的出現。利用public繼承、composition和private繼承。

如果要禁止編譯器自動產生的這些函式,將其宣告為private,並且不給出定義即可。

一些引數的檢查在設計時,盡量能在編譯期就能檢查出錯誤來。

如不同cpp中的變數值如果相互信賴,則初始化順序不同會導致錯誤出現。此時singleton模式可以使用。

《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替換...