TMP 模板元編程
0.explicit建構函式比non-explicit建構函式好。
1.可以用const 來代替#define 定義一個常量。
#define沒有範圍,也沒有封裝性。
class A<br />{<br /> private:<br /> static const int NUM=5;<br />//當常量為static且為整數類型,則可將不需定義式。</p><p>};<br />const int A::NUM;<br /> //NUM的定義。在聲明式中已經獲初值,所以無需在定義式給初值。
//當在類中要聲明一個長度固定的數組,而舊編譯器不能在類中賦初值,所以用enum<br />class A<br />{<br /> private:<br /> enum{NUM=5};<br /> int array[NUM];<br />};
但enum不可以取地址,而const 常量能取地址。因此指標或引用不能指向enum常量。
#define定義宏時,可以用template inline函數代替。
#ifdef/#ifndef 很重要。
const vector<int>::iterator pos; //類似T* const 即指向不變
vector<int>::const_iterator pos; //類似const T* 即指向的元素不變。
函數傳回值後加const 為了避免意外發生。
const int operator+(const A a,const A b)<br />{<br /> return a.num()+b.num();<br />}<br />int c;<br />a+b=c; //如果函數沒加const,則可以錯誤賦值。<br />c=a+b;<br />if(a+b=c) //const 可避免此錯誤
成員函數如果常量性不同就可被重載。
編譯器遵循bitwise constness準則。如果想要實現logical constness,則用mutable改變const值
bitwise constness:只要成員函式宣告為const,則類中任何一個成員都不能變。
logical constness:對於客戶來說不變即可。
當重載成員函數(只有const區別),則非const調用const函數為好,中間可進行強制轉換。
在寫函數時要考慮const。
面對成員變數為const或reference時,他們一定要初始化列表,而不是賦值。
建構函式用初始化列表初始化。
當建構函式的初始化和賦值效率差不多時,則建立private函數存放共同的部分,在多個建構函式中調用。
當兩個類在不同編譯單元中,當一個類要用到另一個類對象時,不知道初始化順序,所以為了確保順序,必須定義一個函數
#include"A.h"<br />class A<br />{<br /> public:<br /> size_t numDisk() const;</p><p>};<br />#include"B.h"<br />class B<br />{<br /> public:<br /> //B(params);</p><p>};<br />/*<br />B::B(params)<br />{<br /> size_t disk=A.numDisk(); //調用時不知道是否已對A初始化<br />}<br />*/
當變為下面時,
/*A& A()
{
static A a;
return a;
}
*/
情況好轉。
這就是傳說的singleton模式。
class FileSystem<br />{<br />public:<br />size_t numDisk() const;<br />};<br />extern FileSystem tfs;<br />class Directory<br />{<br />public:<br />Directory(params);</p><p>};<br />Directory::Directory(params)<br />{<br />size_t disks=tfs.numDisk();<br />}<br />
改進版
class FileSystem<br />{};<br />FileSystem& tfs()<br />{<br />static FileSystem fs;<br />return fs;<br />}<br />class Directory<br />{};<br />Directory::Directory(params)<br />{<br />size_t disks=tfs().numDisk();<br />}<br />Directory& tempDir()<br />{<br />static Directory td;<br />return td;<br />}