1.指針c++
typedef說明一種新類型名,來代替已有類型名。函數
a.案例:typedef char* String_t和#define String_d char *這兩句在使用上的區別?spa
1)前者聲明一個類型的別名,在編譯時處理,有類型檢查。後者是一個簡單的替換,在預編譯時處理,無類型檢查。指針
2)String_t a,b;中a和b都是char*類型的。可是String_d a,b;中a是char*類型的,b是char類型的。對象
b.對 typedef string *pstring;內存
const pstring cstr;的理解。ci
cstr是一種指針,指向string類型的const對象。但這是錯誤的。錯誤的緣由在於將typede看成宏替換似的文本擴展了。聲明 const pstring時,const修飾的是pstring的類型。string
這是一個指針。因此該聲明應該是把cstr定義爲指向string類型對象的const指針。等價於:string * const cstr; 編譯
c.void*指針。void* 指針代表該指針與一地址值相關,可是不清楚存儲在該地址值上的對象類型。void*指針只支持有限的操做:class
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;
};