1. 程式人生 > >《Effictive C++》讀書筆記(一)

《Effictive C++》讀書筆記(一)

一.讓自己習慣C++

1.      視C++為一個語言集合:

C語言基礎,面向物件部分,Template,STL。C++感覺好博大精深,現在貌似還是第二個階段,想起剛學C++那會兒,一直用著C++的語法,寫著面向過程的程式碼,實在是囧啊…

2.      儘量以const ,enum,inline替換#define:

a)        當我們定義一個常量時,最好使用const常量,而非#define,因為define會無腦的替換,這個常量可以是專屬於某處的,而#define所定義的是全域性的。

b)        使用enum類似於#define,但是效果更好,而且enum也可以作為int型別的變數使用。

c)        有時候我們會用#define來定義一個函式,這樣做很方便而且沒有呼叫函式的開銷,但是這樣的函式很容易出問題。而我們使用inline函式,加上模板可以更好地的實現這種效果。

d)        雖然#define可以被這麼多種東西替代,但是#define還是必不可少的。#ifndef/#ifdef更是對編譯流控制的好方法。

3.      儘可能地使用const:

a)        防止意外修改不該被修改的內容,使之儘早在編譯時暴露出來。Const可以修飾任何物件,函式引數,函式返回型別,成員函式本體

b)        對於成員函式,如果不希望其改變物件,可以宣告為const的。

c)        const版本和non-const版本的成員函式實現等價時,可以令non-const版本的呼叫const版本的,使用const_cast去除const即可。

4.      保證物件在使用前被初始化:

a)        在使用物件或者變數前,保證其被初始化,防止其為隨機值。

b)        對於類的建構函式,最好使用成員初值列表(member initialization list)來初始化,初值列的成員變數排列次序與宣告次序相同(這個不是強制,但是最好如是執行,比如我們申請一個數組,陣列大小需要先有初值才行)。而不要用建構函式內進行賦值操作(assignment),這樣會先預設初始化再賦值,相當於兩次操作。

c)        跨編譯單元的初始化順序,以local static物件替換non-local-static物件。說實話這條沒看懂...不過我的簡單理解就是類似單例模式,我們在使用物件時,有時候不確定初始化的時機,那麼我們不如在使用前,將要用的東東一起初始化了。這樣就可以控制順序了。

二.構造,析構,賦值運算

5.瞭解C++默默編寫並呼叫了哪些函式

a)      如果我們什麼都不寫的話,編譯器也會為我們生成預設建構函式,解構函式,拷貝建構函式,以及一個賦值運算子。

b)      如果我們自己聲明瞭這些函式,那麼C++會使用我們自己編寫的這些函式,不會再使用那些預設的。

c)      編譯器為我們生成的預設建構函式是沒有引數的,如果我們聲明瞭其他的有引數的建構函式,那麼這個預設建構函式也會消失,我們如果仍想要無引數的建構函式,那麼就要自己再宣告一個。

d)      編譯器為我們生成的解構函式,不會是virtual的,除非這個類的基類有virtual解構函式。

6.若明確不想使用編輯器自動生成的函式,就應該明確拒絕

a)有時候我們不容許拷貝或者賦值一個物件時,即使我們不寫拷貝或者賦值函式,編譯器也會為我們生成一個,腫麼辦呢?答案是自己寫一個private的拷貝建構函式和賦值函式,這樣從類外就不能呼叫了。但是從類內還是可以呼叫的,這時候,我們可以只宣告,而不定義,這樣,即使有人不小心使用了,在編譯連結的時候,也會報錯。把錯誤提前暴露,才容易發現。

b)如果我們怕忘記,或者為了方便,也可以定義一個基類uncopyable,讓我們的類繼承這個類即可。

7.為多型基類宣告虛解構函式:

a)      如果我們不這樣做,當使用基類指標控制子類物件時,當析構時會發生只析構基類部分,而子類部分不被釋放的尷尬情況。導致記憶體洩露。

b)      但是這也不代表著為了保險起見,我們全都要用virtual解構函式,因為虛擬函式的開銷是比較大的,所以一般判定需要使用虛解構函式的條件為:只要這個類中有一個其他的虛擬函式,那麼就使用虛解構函式。

c)      既然要使用多型的特性,那麼如果基類不是虛解構函式,那我們就不要去繼承這個類,不然會引出一大串麻煩。比如string,標準stl等都是非虛解構函式的!(前提是使用多型特性)

d)      解構函式呼叫的順序:基類的解構函式先呼叫,然後依次向下呼叫子類的解構函式。

8.別讓異常逃離解構函式:

a)      我的理解感覺就是,能不丟擲異常的,或者感覺會丟擲異常的功能,不要放在解構函式中,額外設定一個函式。比如.close()關閉函式。但是,在解構函式中仍然要做一下關閉的操作,防止客戶忘記呼叫close發生異常。但是,在解構函式中的異常,不要丟擲,可能會導致程式提前結束。應該在解構函式中就catch並處理。

b)      被解構函式呼叫的函式如果丟擲異常,解構函式也應該catch掉,保證不要再丟擲。

c)      如果客戶需要對某個操作函式執行期間的異常做出反應,那麼最好提供一個普通函式,而不要把這個東東放在解構函式中。

9.絕不在構造和解構函式中呼叫virtual函式:

a)      我們知道,如果有繼承,建構函式會先呼叫父類建構函式,而如果建構函式中有虛擬函式,此時子類還沒有構造,所以此時的物件還是父類的,不會觸發多型。更容易記的是基類構造期間,virtual函式不是virtual函式。

b)      解構函式也是一樣,子類先進行析構,這時,如果有virtual函式的話,子類的內容已經被析構了,C++會視其父類,執行父類的virtual函式。

c)      總之,在構造和解構函式中,不要用虛擬函式。如果必須用,那麼分離出一個Init函式和一個close函式,實現相關功能即可。

10.令operator=返回一個referenceto *this:

我們經常會為我們的類寫一個operator=的函式,為了保證連鎖賦值,比如x= y=z的這種情況能正常執行,最好是返回一個*this的引用。

11.在operator=中處理“自我賦值”:

a)      自我賦值看起來不是那麼容易發生,但是程式複雜了什麼情況都有,所以為了我們程式的健壯性,還是要處理一下的。

b)      自我賦值會導致程式出錯的情況在於,如果欄位中有指標,先刪除指標原來指向的物件,指向=右邊的物件。而自我賦值時會導致原來的物件被刪除,而=右邊的物件也被刪除,因而會出錯。

c)解決的方法其實最簡單的就是先判定是否相等,如果和自己是同一個物件,直接返回*this,結束。

12.複製一個物件時勿忘其每一個成分:

a)      正常情況下,如果我們不寫拷貝建構函式,編譯器會為我們生成一個預設的拷貝建構函式,但是這個函式只能實現淺拷貝,如果要實現深拷貝就必須要自己寫一個拷貝建構函式。

b)      但是如果我們自己寫了拷貝建構函式,就一定要拷貝每一個成分,如果忘記了某個成分,編譯器是不會提醒的。尤其在發生繼承的時候,更加需要注意拷貝基類成員部分。通過呼叫基類函式來進行拷貝。

c)      關於initialization和assignment:前者由建構函式執行,後者由operator =執行。兩者對應不同的函式動作。兩者可能有差不多的內容,但是不要使用一個呼叫另一個函式,如果實在想要抽象,不如提取一個Init函式。

相關推薦

Head First C 讀書筆記

一段程式碼: #include <stdio.h> int main(){ char cards[] = "JQK";//editable, copy is in stack //

Effictive C++》讀書筆記

一.讓自己習慣C++ 1.      視C++為一個語言集合: C語言基礎,面向物件部分,Template,STL。C++感覺好博大精深,現在貌似還是第二個階段,想起剛學C++那會兒,一直用著C++的語法,寫著面向過程的程式碼,實在是囧啊… 2.      儘量以con

深度探索C++對象模型讀書筆記

復雜 理解 image play 基礎上 isp 靜態 布局 bject 《深度探索C++對象模型》這本書也算是學習C++面向對象編程的必備書了,打算花上幾天先簡單的看一遍,這種書看上好幾遍也不一定能理解太多,慢慢積累一點一滴吃透就好。下面把我看書過程中覺得比較有意義的摘錄

C陷阱與缺陷讀書筆記

之間 之前 符號 雙引號 陷阱 數組 調用 筆記 如果 第一章 1.2 按位運算符:& 邏輯運算符:&& 1.3 單字符符號:只有一個字符長 多字符符號:含多個字符

C#從現象到本質》讀書筆記

托管代碼 操作 擁有 底層 不同 使用 子集 存在 基於 最近根據博客園大神的推薦,買了本《C#從現象到本質》。做一點讀書筆記。 由於不懂IL和ldsdm,winddg,太深奧,理解不了,就牛嚼草一樣,先總結第一遍讀書,自己總結的知識點了。不知道這樣會不會侵權,如果侵權了,

《深度探索C++物件模型》讀書筆記

Lippman早期在貝爾實驗室,和C++發明者Bjarne Stroustrup設計了全世界第一套C++編譯器cfront,還著有經典的C++入門書Ensential C++和C++ Primer。 全書基本以cfront的設計方法為基礎,討論編譯器如何處理C

C#入門經典》再次閱讀時的讀書筆記

第1章 C#簡介 1.Net Framework是Microsoft為開發應用程式而建立的一個富有革命性的新平臺,它可以建立Windows應用程式,Web應用程式,Web服務和其他各種型別的應用程式. 2.編譯.Net Framework庫的程式碼時,先將其編譯為MSIL(M

《程式碼揭祕--從C/C++的角度探祕計算機系統》讀書筆記

最近在看左飛哥的一本書:《程式碼揭祕--從C/C++的角度探祕計算機系統》。我覺得寫得很好,下面是書中的一小段程式,經過我修改。 #include <iostream> using namespace std; int main(void) { char

C++primer讀書筆記

1.endl操縱符  效果:結束當前行,並將與裝置關聯的緩衝區(buffer)中的內容刷到裝置中。緩衝重新整理操作可以保證到目前為止程式所產生的所有輸出都真正寫入輸出流中,而不是僅停留在記憶體中等待寫入輸入流。//在除錯時新增列印語句,這類語句應該保證“一直”重新整理流。否則

Objective-C高階程式設計 iOS與OS X多執行緒和記憶體管理 讀書筆記

1.2.2 記憶體管理原則: 自己生成的物件,自己所持有 非自己生成的物件,自己也能持有 不再需要自己持有的物件時釋放 非自己持有的物件無法釋放 自己生成的物件,自己所持有 //自己生成並持有物件 id obj = [[NSObject alloc] init]; //自己持有物件   

《代碼閱讀》讀書筆記

需求 的人 一行 編碼 重要 流動 使用 分析 缺少 《代碼閱讀》讀書筆記(一) 《代碼閱讀》(《Code Reading The Open Source Perspective》)Diomidis Spinellis 著 ---------------------

SICP讀書筆記

自由 運用 實參 隱藏 更多 定義 並不是 謂詞 精確 第一章 構造過程抽象 計算過程是存在於計算機裏的一類抽象事物,它在演化過程中會去操作一些被稱為數據的抽象事物。我們通過創建被稱為程序的規則模式來指導這類過程的進行。程序由程序設計語言編排而成。 我們將要使用Lisp

崔華基於oracle的SQL優化讀書筆記如何得到真實的執行計劃

hash mes getting binary oracl only 中文 fun roc ---恢復內容開始--- 得到目標SQL的執行計劃,大致有以下四種方式: 1.explain plan 命令 2.DBMS_XPLAN包 3.SQLPLUS中的autotrace開關

C++學習筆記——一個字符串分割和統計的工具TextUtils

發生 插入 exit 大小 按行讀取 位置 n) fstream ostream 第一講先從一個實例開始——我們需要完成一個遍歷文件並統計單詞出現次數的任務。分解功能:首先,按行讀取文件並舍棄可能的空行。其次,將每一行都按照空格劃分單詞。因為可能存在標點符號,我們還需要將標

《可愛的Python》讀書筆記

可愛的Python 閏年 素數 質數 Just use it! don't learn!——只用,不學!無意間了解到《可愛的Python》就被它的名字所吸引。查了書評得知這本書是有爭議的,有人覺得書中很多都是點到為止不適合新手入門,處處給讀者挖坑,結構混亂更不能作為參考書。有人認為此書

《Python網絡數據采集》讀書筆記

urllib BeautifulSoup 思考“網絡爬蟲”時通常的想法:? 通過網站域名獲取 HTML 數據? 根據目標信息解析數據? 存儲目標信息? 如果有必要,移動到另一個網頁重復這個過程當網絡瀏覽器遇到一個標簽時,比如<img src="cuteKitten.jpg"&

《用戶網絡行為畫像》讀書筆記

感覺 數據結構 定性 角度 筆記 穩定性 包括 習慣 收藏 推薦就是發掘用戶集合和對象集合的語義關系,為用戶提供語義最相關的 TOP-N 對象集合。 語義關系就是能讀懂用戶偏好興趣的核心。 推薦系統是面向具體業務的交叉研究,無業務講推薦系統,感覺言之無物;從技術來講,不同的

《編碼-隱匿在計算機背後的語言》 —— 讀書筆記:編碼

分享圖片 信號 組合 大小寫 不變 缺點 改變 有著 書寫 1. 至親密友 1) 什麽是編碼?編碼是一種用來在機器與人之間傳遞信息的方式,編碼就是交流。 2)莫爾斯電碼,只有點和劃(國際求救信號:SOS ...---...),缺點是不區分大小寫。

《軟件測試方法和技術》-讀書筆記

圖片 軟件工程 AI 開發 支持 ont 3年 發的 一次 軟件測試正反兩方面的爭辯 軟件測試領域先驅 Bill Hetzel 博士 1993年在美國的北卡羅來納大學組織了歷史上第一次正式的關於軟件測試的會議。從此以後,軟件測試開始頻繁出現在軟件工程的研究和實踐中,也可以認

《黑客與畫家》讀書筆記

能說 互聯 可能 研究 歷史 設計 職位 天下無敵 聯網 《黑客與畫家》讀書筆記(一) 黑客與畫家 黑客與畫家的共同之處,在於他們都是創作者,都試圖創作出優秀的作品。 他們本質上都不是在做研究,雖然過程中可能發現一些新技術。黑客的出發點是原創,最終得到一個優美的結果;科學家