1.指針
typedef說明一種新類型名,來代替已有類型名。
a.案例:typedef char* String_t和#define String_d char *這兩句在使用上的區別?
1)前者聲明一個類型的別名,在編譯時處理,有類型檢查。后者是一個簡單的替換,在預編譯時處理,無類型檢查。
2)String_t a,b;中a和b都是char*類型的。但是String_d a,b;中a是char*類型的,b是char類型的。
b.對 typedef string *pstring;
const pstring cstr;的理解。
cstr是一種指針,指向string類型的const對象。但這是錯誤的。錯誤的原因在於將typede當作宏替換似的文本擴展了。聲明 const pstring時,const修飾的是pstring的類型。
這是一個指針。所以該聲明應該是把cstr定義為指向string類型對象的const指針。等價於:string * const cstr;
c.void*指針。void* 指針表明該指針與一地址值相關,但是不清楚存儲在該地址值上的對象類型。void*指針只支持有限的操作:
1)與另外一個指針進行比較
2)向函數傳遞void*指針或從函數返回void*指針。
3)給另外一個void*指針賦值。不允許使用void*指針操作他所指向的對象。當函數返回void*類型時,表示返回一個特殊指針類型。而不是返回類型為void那樣表示無返回值。
d.用typedef簡化函數指針的定義
typedef bool (*cmpFcn)(const string &,const string &);
該定義表示cmpFcn是一種指向函數的指針類型的名字。該指針類型為指向返回bool類型並帶兩個const string 引用形參的函數的指針,在要使用這種函數指針類型時,
只需直接使用cmpFcn即可,不必每次都把整個類型聲明全部寫出來。
在引用函數名但又沒有調用該函數時,函數名將被自動解釋為指向函數的指針。
bool lengthCompare(const string &,const string &);
直接引用函數名等效於在該函數名上應用取地址操作符:
cmpFcn pf1=lengthCompare;
cmpFcn pf2=&lengthCompare;
函數指針的使用
指向函數的指針可以用於調用他所指向的函數。可以不需要使用解引用操作符,直接通過指針調用函數。
例如: typedef bool(*cmpFcn)(const string &,const string &);
bool lengthCompare(const string &,const string &);
則:cmpFcn pf=lengthCompare;
lengthCompare("hi","bye"); //直接調用lengthCompare函數
pf("hi","bye"); // 利用函數指針調用lengthCompare函數,未使用*
(*pf)("hi","bye"); // 利用函數指針調用lengthCompare函數,使用*
函數的形參為指針和返回指向函數的指針
允許將形參定義為函數類型,但是函數的返回類型則必須是指向函數的指針,而不能是函數。具有函數類型的形參所對應的實參將被自動轉換為指向相應函數類型的指針。
但是,當返回的是函數類型時,同樣的轉換操作將無法實現。
func f2(int); //錯誤,func無法自動轉換。
func* f3(int); //正確,f3返回一個函數指針
2.引用
引用就是對象的另外一個名字。c++中規定一旦定義了引用,就必須把它跟一個變量綁定起來,並且不能修改這個綁定。
不能定義引用類型的引用,但是可以定義其他類型的引用。
使用引用和指針都可以間接的訪問另外一個值,但是他們之間有幾個重要的區別。
1)引用不能為空,當引用被創建時,他必須被初始化,而指針可以為空值,可以在任何時候被初始化。
2)一旦一個引用被初始化為指向一個對象,他就不能改變為對另外一個對象的引用,指針則可以在任何時候指向另外一個對象。
3)不可能有NULL引用。必須確保引用和一塊合法的存儲單元關聯。
4)sizeof(引用)得到的是所指向變量(對象)的大小,而sizeof(指針)得到指針本身的大小。
5)給引用賦值修改的是該引用所關聯的對象的值,而並不是使引用於另外一個對象的關聯。
6)引用使用時不需要解引用,而指針需要解引用,引用和指針的自增(++)操作符運算意義不同。
7)如果返回動態分配的對象或內存,必須使用指針,引用可能引起內存泄漏。
8)當使用&運算符取一個引用的地址時,其值為所引用變量的地址。而對指針使用&運算,取得是指針變量的地址。
可見引用本質只是一個對象的別名。對引用別名的操作即是對本身變量的操作。
const引用
const引用是指向const對象的引用。當引用的對象是const對象時,引用也必須是const。
const int ival=1024;
const int &refVal=ival; //正確
int& ref2=ival; //錯誤
如果既要既要利用引用提高程序的效率,又要保護傳遞給函數的數據不在函數中被改變,就應該使用常引用。常引用主要用於定義一個普通變量只讀屬性的別名。
作為函數的傳入形參,避免實參在調用函數中被意外改變。
引用做類的數據成員
引用類型數據成員的初始化有一下幾個特點:
1)不能直接在構造函數中初始化,必須用到初始化列表。
2)凡是用引用類型的數據成員的類,必須定義構造函數。
案例:
class ConstRef{
public:
ConstRef(int ii):i(ii),ci(i),ri(ii){} //ci與ri必須在成員初始化列表中初始化,因此必須自定義構造函數,書寫成員初始化列表
private:
int i;
const int ci;
int &ri;
};