附錄
std 命名空間是所有C++ 標(biāo)準(zhǔn)庫的棲身處
然而C 標(biāo)準(zhǔn)程序庫耶適用于C++ 內(nèi)。
signature 簽名:
函數(shù)的聲明揭示簽名式。 也就是參數(shù)和返回類型。
看到賦值語句也要小心, 因?yàn)?語法也可以用來調(diào)用copy 構(gòu)造函數(shù):
Widget w3 = w2 //調(diào)用copy 構(gòu)造函數(shù)
幸運(yùn)的是copy構(gòu)造和 賦值 很容易區(qū)別。 如果一個新對象被定義菊碟, 一定會有個 構(gòu)造函數(shù)被調(diào)用。
STL: 標(biāo)準(zhǔn)模板庫在刺, 是C++標(biāo)準(zhǔn)程序庫的一部分逆害。
接口:一般討論的是函數(shù)的簽名或者class 的可訪問元素
條款1 :
STL 中的迭代器和函數(shù)都是在C指針上塑造出來的, 所以對STL 的迭代器和函數(shù)對象而言蚣驼, 舊式的C pass by value 守則很適用
條款2:盡量用enum const inline 替換 define
1.因?yàn)楸籨efine 的標(biāo)記 也許從未被編譯器看見魄幕, 所以沒進(jìn)入記號表,當(dāng)你運(yùn)用此變量但獲得一個編譯錯誤信息時颖杏, 可能回帶來困惑纯陨。
常量定義式通常被放在頭文件, 以便被不同的源碼include.
2.對于class 的專屬常量
class GamePlayer
{
? ? public:
static const int NumTurns = 5; // 常量表明式
}
只要不取NumTurns的地址留储, 就可以不在實(shí)現(xiàn)文件那里提供定義式翼抠。
const int GamePlayer::NumTurns;? // 不給予數(shù)值也可以, 因?yàn)樵诼暶魈幰呀?jīng)賦了初值
唯一例外時當(dāng)你在class 編譯階段需要一個class常量值時获讳, 萬一你的編譯器不接受static整數(shù)型 class 常量完成 in class 初值設(shè)定阴颖, 就可以用the enum hack 補(bǔ)償做法
class GamePlayer:
{
private:
? ? ? ? enum{ NumTurns = 5 };
? ? ? ? int scores[NumTurns];
}
因?yàn)镋nums 和 define一樣不導(dǎo)致非必要的內(nèi)存分配。
另外一種情況時#define的誤用情況
#define? CALL_WITH_MAX(a,b)? f((a)> (b) > (a) : (b))
當(dāng)調(diào)用時
CALL_WITH_MAX( ++a, b) // a 被累加二次
所以改寫成 template inline 函數(shù)
template<typename T>
inline void callWithMax( const T & a, const & b)
{
? ? f( a > b ? a : b) ;
}
條款3: 盡量使用 const ??
const的作用: 給編譯器添加約束丐膝, 告訴其他程序員和編譯器 這個值不變
例如:
class Rational{ ... } ;
const Rational operator * (? const Rational & lhs, const Rational & rhs);
如果不加const的話 (a * b) = c就會出現(xiàn)量愧。
const 成員函數(shù)
目的:
使 class 接口 比較容易被理解, 這樣得知哪個對象可以改動對象內(nèi)容而哪個函數(shù)不行是很重要的
操作const 對象(class 的對象)成為可能尤误, 有const 成員函數(shù)來處理取得修飾的const 對象
如:
const TextBlock ctb ("World");
std:cout >>? ct b[0]; // 調(diào)用const TextBlock operator [] const;
所以 一般函數(shù)里 ? void print( cosnt TextBlcok& ctb )
{
? ? ? ? std :: cout <<? ctb[0];
? ? ? ? ....
}
只要operator [] 重載并對不同版本給予不同的返回類型。 就可以有不同的處理结缚。
另外:
non- constt operator[] 的返回類型是reference to char, 不是char. 如果operator[]? 是返回一個char. 那么 tb[0] = 'x'
一般來說 定義const函數(shù)是想讓對象內(nèi)的任何一個bit不受更改损晤, 因此const成員函數(shù)不可以更改對象內(nèi)任何non-static的成員變量。?
但是這樣的觀點(diǎn)存在一個問題红竭,當(dāng)const成員函數(shù)返回一個非const 量尤勋, 那么可以更改對象內(nèi)的數(shù)據(jù)喘落。
使用mutable 可以讓non-staic成員變量的bitwise constness約束解除
另外一種解決辦法是讓non- static 函數(shù)調(diào)用 const-static函數(shù)
char & operator[] ( std ::? size_t position)
{
? ? ? ? return const_cast < char &> (static_cast <const TextBlock &> ( * this) [position];?
{
const_cast 去除 const?
static_cast 添加 const (針對對象本身)
條款4? 確定對象被使用前已先被初始化?
對于想default 狗仔一個成員變量, 同樣可以使用 member initialization list? 初始化
例如:
ABEntry:: ABEntry():theName(), theAddress(), thePhones(), numTimesConsulted()
{
}
對于不同的源碼文件最冰, 每一個內(nèi)含 一個non-local static 對象瘦棋。 如果編譯單元內(nèi)的某個 non-local static 對象使用了另外一個編譯單元的 non-lcaol-static 對象, 它所用到的這個對象可能尚未被初始化暖哨, 那么會出現(xiàn)初始化次序的重要性問題赌朋。
解決辦法:?
將這些對象放到自己的專屬函數(shù)內(nèi)。 這些函數(shù)內(nèi)返回一個reference 指向它包含的對象篇裁。 用戶調(diào)用這些函數(shù)沛慢。
保證獲得那個reference 將指向一個歷經(jīng)初始化的對象。
總結(jié):
手動初始化內(nèi)置型 non-member ( 賦值和初始化的花費(fèi)差不多)
使用成員初值列 對付對象的所有成分
最后在初始化次序不確定性 加強(qiáng)設(shè)計