Effective C++學習筆記(一)
前言
此書由Scott Meyers所著,侯捷所譯,乃經典中的經典,十分值得多刷。此文旨在記錄書籍重點內容,並附上個人除錯與理解
原書中含有較多譯者未予翻譯的英文詞條,這裡給出大致參照
英文詞條 | 中文翻譯 | 英文詞條 | 中文翻譯 |
---|---|---|---|
const | 常量 | non-const | 非常量 |
static | 靜態 | non-static | 非靜態 |
heap | 堆區 | stack | 棧區 |
by value | (以)值(的方式) | by reference | (以)引用(的方式) |
base class | 基類(父類) | derived class | 派生類(子類) |
一.讓自己習慣C++
條款01:視C++為一個語言聯邦
View C++ as a federation of languages
在C++誕生初期,它的名稱為C with Classes,可以視作它只是C加上一些面向物件的特性。但隨著C++的逐漸發展,已經逐漸演變為一個同時支援過程形式、面向物件形式、函式形式、泛型形式、超程式設計形式的語言。總的來說我們應將C++視作一個語言聯邦,分為以下四種
- C:內建資料型別,陣列,指標,語句...等等統統來自C語言
- Object-Oriented C++:最初的C with Classes,包含了類,封裝,繼承,動態繫結...等等面向物件的設計
- Template C++:模板,泛型程式設計
- STL:一個template
條款02:儘量以const,enum,inline替換#define
Prefer consts, enums, and inlines to #define
傳統藝能,在C風格的資料結構訓練中,我們常用以下幾種巨集定義
#define ERROR -1
#define FALSE 0
#define OK 1
由於各種不可抗力,可能導致ERROR,FALSE等在編譯器開始處理原始碼之前就被從前處理器上移除了,並沒有進入到記號表中,使後續的程式碼錯誤資訊可能指出錯誤來自於“-1”或是“0”而非ERROR或是FALSE。哦!這糟糕的程式碼將讓您一頭霧水!
正如條款所說的,儘量以const替換#define
const int Error = -1; //全大寫風格一般用於巨集
另一種情況,由於編譯器認為必須在編譯期間便知道陣列的大小,故在構建中傳入變數或是non-static的常量均是不合法的,下面以一個類成員作示範
#define ARRAYSIZE 10
class GamePlayer {
private:
int scores[ARRAYSIZE]; //傳統做法
static const int ArraySize = 10; //ArraySize常量宣告式
int scoresBetter[ArraySize]; //優化做法
};
//const int GamePlayer::ArraySize; //部分編譯器可能仍需要你寫出這行程式碼
//無需也不能夠賦初值,原因:為const常量
眾所周知,若要在類內寫一個靜態成員變數,需要在類內宣告,然後再在類外實現。但對於整數型別(例如int,char,bool)來說,編譯器可以對其做出特殊處理,也就是 “in-class初值設定”。但若對於float亦或是double型別的變數,就需要走老路子了
class CostEstimate {
private:
static const double FudgeFactor; //該類一般寫在標頭檔案中 CostEstimate.h
};
const double CostEstimate::FudgeFactor = 1.23; //該定義式寫在實現檔案中 CostEstimate.cpp
上述例子中對ArraySize的初始化被稱為 “in-class初值設定”,若某些編譯器不支援此種做法,那麼你需要在類外書寫ArraySize常量定義式,就像下面這樣