1. 引用類型。很多初學(xué)者對引用這種數(shù)據(jù)類型存在誤解,認(rèn)為使用它時需要取地址,并且容易把它和指針搞混淆,比如下面的程序代碼片段: void fun(int& a,int& b) { int c=8; &a=c ; //錯誤,a是引用類型的變量,不能對它取址做左值。 b=&c; //錯誤,b是引用類型的整形變量,不能將一個整形變量的地址賦值給它。 …. } int main() { int m=5,n=6; fun(&m,&n); //錯誤,m和n要傳遞給引用類型的形參,相當(dāng)于要完成初始化賦值操作。 .... return 0; } 其實(shí),引用類型的很好理解,你只要記住以下三點(diǎn): 1) 引用類型的變量是被引用變量的別名。 2) 引用類型的變量和被引用變量共同占用一塊內(nèi)存。 3) 引用類型一經(jīng)初始化,就把它看成是個變量,對它的后續(xù)操作和對變量是一樣的。 例如下面的程序代碼片段: int main() { int a=5; int *p=NULL; int& b=a; //正確,此時的b是“int&”這種引用類型,它是變量a的別名。 b=7; //正確,因?yàn)閎和a共同占用一塊內(nèi)存,所以對b改變引起a的改變。 p=&b; //正確,b經(jīng)初始化是一個變量,把b的地址賦值給指針p合情合理。 } 通過以上的說明,你應(yīng)該對引用類型有了正確的理解。 2. typedef關(guān)鍵字。很多初學(xué)者認(rèn)為typedef就是為一個數(shù)據(jù)類型起個別名,其實(shí)這是不準(zhǔn) 確的,例如下面的一個語句: typedef char array[80]; //這里難道是將a[80]作為char的別名? 顯然不是,這里其實(shí)用typedef來說明此處的array是一個含有80個char字符的數(shù)組,我們可以用: array a,b; //此時的a,b均是array這種類型,即含有80個char 字符的數(shù)組。 使用typedef可以使我們的定義更加的容易理解,特別是在解釋一個非常復(fù)雜的函數(shù)原型時,例如linux下的信號處理函數(shù): void ( *signal (int signo,void (*func) (int) ) ) (int); // 這個原型你看得費(fèi)力不? 此時,我們可以用: typedef void sigfunc (int); //此時的sigfuc是一種函數(shù)指針類型 sigfunc *signal (int ,sigfunc *); //此時signal函數(shù)是帶有兩個參數(shù),一個int類型,一個函數(shù)指針類型,并且它的返回類型是函數(shù)指針類型,而這個函數(shù)指針是指向一個無返回類型帶一個int類型參數(shù)的函數(shù)。這樣理解是不是清楚一點(diǎn)。 3. 內(nèi)聯(lián)函數(shù)。很多初學(xué)者認(rèn)為內(nèi)聯(lián)函數(shù)就像宏一樣,但比宏安全一點(diǎn)。其實(shí)這是不對的內(nèi)聯(lián)函數(shù)可以說是C++的一大優(yōu)點(diǎn),它有宏替換一樣的效率,又有宏定義不具備的安全性, C++的類的體內(nèi)定義的那部分函數(shù),編譯器會默認(rèn)是內(nèi)聯(lián)函數(shù),而不管它加沒有加inline這樣一個關(guān)鍵字,例如: class A { public: int getsize() {return _size} int getlength() {return _length} }; //上面的兩個成員函數(shù)都是內(nèi)聯(lián)函數(shù)。 另外,不是你定義一個內(nèi)聯(lián)函數(shù),它就是內(nèi)聯(lián)函數(shù),這是因?yàn)閮?nèi)聯(lián)函數(shù)是由編譯器決定,你向編譯器申請一個內(nèi)聯(lián)函數(shù),如果里面的代碼量太大了的話,是申請不到的,因?yàn)閮?nèi)聯(lián)函數(shù)的代碼是放在符號表中的。在使用時直接進(jìn)行替換。而符號表資源是有限的。 但是內(nèi)聯(lián)函數(shù)是函數(shù),編譯時期會去檢查它的函數(shù)語法,形參類型是否正確等等。 4. this指針。很多人對this指針不理解,覺得它很詭異,當(dāng)然也就存在很多誤解,的確this指針比較的隱晦難懂。其實(shí)你只要記住以下幾點(diǎn)就可以了: 1) this指針是編譯器定義的一種指針變量,它存在于ecx寄存器中。 2) this指針的作用域是在類的體內(nèi)。 3) this指針是通過成員函數(shù)調(diào)用時,傳過去的。比如: class a { void fun(){} }; int main() { a obj; obj.fun() //其實(shí)在這里編譯器會自動把它轉(zhuǎn)換成 fun(&obj),此時this就指向了obj了。 } 4) 一個類中的多個對象都是用this指針來指定的,this指針只有一個,但它是指針,可以指針不同的對象。 5) 當(dāng)有一個基類和一個派生類對象時,若有且僅有派生類的一個對象,那么基類的this指針指向派生類對象。 5 const關(guān)鍵字。這個修飾詞被很多人誤解,有人認(rèn)為它修飾的變量只讀,也有人認(rèn)為它不分配內(nèi)存的,這些說法都是不準(zhǔn)確的。其實(shí)const可以用來修飾非常多的類型還可以修飾函數(shù),它在某些情況下不分配內(nèi)存,而在另外一些情況分配內(nèi)存。不管const修飾的是什么,你只要記住一點(diǎn),const直接修飾的變量或函數(shù),是針對這個變量本身的。比如下面的程序段代碼: int main(){ int b=10; const int size=100; int array[size]; //類似于宏替換,在編譯時直接替換,所以size是在符號表中不占內(nèi)存 const int m[]={5,6,7,8}; //此時數(shù)組的各元素值是只讀的,并且為這個數(shù)組分配的內(nèi)存。 const int *p=&b; //此時只是修飾了p這個指針指向一個數(shù)據(jù)時,只能有只讀屬性操作。 b=12; //正確的,b可以做改變,因?yàn)閏onst修飾的是指針。 int* const pn=&b; //正確的,也是修飾指針,但修飾的是指針存放的地址是只讀的。 return 0; } 記住const是個修飾詞,一定要搞清楚它所修飾的對象是誰,修飾的對象的哪部分屬性然后就把修飾的那部分屬性看成是只讀的就行了。 |