01.視C++為一個語言聯邦
- C
- Object-Oriented C++
- Template C++
- STL
過程形式(procedural),面向對象形式(object-oriented),函數形式(functional),泛型形式(generic),元程式設計形式(metaprogramming)
問題:
泛型形式和元程式設計形式的差別?
過程形式和函數形式的差別?
結論:
對于内置類型而言pass-by-value通常比pass-by-reference高效。
02.盡量以const,enum,inline替換#define
char * const 指針不可更改
const char* 指針指向内容不可更改
define存在的問題:
- 編譯錯誤資訊中無法展示宏名稱,造成定位問題不夠高效。define不會進入符号表。
- define變量未加括号引入問題。
- define替換變量使用++時引入問題。
#define CALL_WITH_MAX(a,b) f((a) > (b) ? (a) : (b))
CALL_WITH_MAX(++a,b); // a被累加兩次,和預期不符
結論:
對于單純常量,以const對象或enum替換define
對于類似函數形式的宏,以inline函數替換define
遺留問題:
enum的詳細使用
03.盡量使用const
作用:
- 修飾global或namespace作用域中的常量
- 修飾檔案,函數,區塊作用域被聲明為static的對象
- 修飾classes内部的static和no-static成員變量
- 修飾指針
char greeting[] = "hello"; char* p = greeting;// non-const pointer,no-const data const char* p = greeting;// non-const pointer,const data char* const p = greeting; // const pointer,non-const data const char* const p = greeting;// const pointer,const data const vector<int>::iterator itr;// const itr,no-const data vector<int>::const_iterator itr;// non-const itr,const data
函數傳回constclass Rational {}; const Rational operator* (const Rational& lhs, const Rational& rhs); // 聲明傳回const為了避免執行如下操作 Rational a,b,c; (a*b) = c; // 避免執行如下無意義的操作 if (a*b = c)
遺留問題:提領操作符重載的格式(參數格式和乘法操作符格式不同)
new操作符重載
const 成員函數
class TextBlock { char& operator[] (size_t position) const { return text[position]; } // for const對象 char& operator[] (size_t position) { return text[position]; } // for no-const對象 string text; } TextBlock tb; tb[0]; // 調用no-const TextBlock::operator[] const TextBlock ctb; ctb[0]; // 調用const TextBlock::operator[]
如果operator[] 傳回char,tb[0] = 'x'無法編譯通過,因為如果函數類型是内置類型,那麼改動函數傳回值不合法。
mutable,釋放掉non-static成員變量的bitwise constness限制,const成員函數可以修改成員變量。
在const和non-const成員函數中避免重複:
- 提取公共函數
- 有non-const函數調用const函數
遺留問題:c++四種轉換class TextBlock { const char* operator[] (size_t position) const {} char* operator[] (size_t position) { return const_cast<char&>( static_cast<const TextBlock&>(*this)[position] ); } }
04.确定對象被使用前已先被初始化
問題:
類中内置資料類型是否會被初始化?(不會被初始化)
結論:
成員變量按照聲明的順序進行初始化。
全局靜态對象通過在函數中使用local static來代替,解決依賴初始化順序的問題。