天天看點

C/C++何時使用引用和指針

指針和引用的差別見本人部落格:http://blog.csdn.net/wyg1065395142/article/details/52198247

指針與引用何時使用呢,首先我們看More Effective C++ 中的詳細條款講述:

條款一:指針與引用的差別

指針與引用看上去完全不同(指針用操作符‘*’和‘->’,引用使用操作符‘&’),但是它們似乎有相同的功能。指針與引用都是讓你間接引用其他對象。你如何決定在什麼時候使用指針,在什麼時候使用引用呢?

首先,要認識到在任何情況下都不能用指向空值的引用。一個引用必須總是指向某些對象。是以如果你使用一個變量并讓它指向一個對象,但是該變量在某些時候也可能不指向任何對象,這時你應該把變量聲明為指針,因為這樣你可以賦空值給該變量。相反,如果變量肯定指向一個對象,例如你的設計不允許變量為空,這時你就可以把變量聲明為引用。

“但是,請等一下”,你懷疑地問,“這樣的代碼會産生什麼樣的後果?”

char *pc = 0;// 設定指針為空值

char& rc = *pc;// 讓引用指向空值

這是非常有害的,毫無疑問。結果将是不确定的(編譯器能産生一些輸出,導緻任何事情都有可能發生),應該躲開寫出這樣代碼的人除非他們同意改正錯誤。如果你擔心這樣的代碼會出現在你的軟體裡,那麼你最好完全避免使用引用,要不然就去讓更優秀的程式員去做。我們以後将忽略一個引用指向空值的可能性。

因為引用肯定會指向一個對象,在C裡,引用應被初始化。

string& rs;// 錯誤,引用必須被初始化
string s("xyzzy");
string& rs = s;// 正确,rs指向s
           

指針沒有這樣的限制。

string *ps;// 未初始化的指針

// 合法但危險

不存在指向空值的引用這個事實意味着使用引用的代碼效率比使用指針的要高。因為在使用引用之前不需要測試它的合法性。

void printDouble(const double& rd)
{
cout << rd; // 不需要測試rd,它肯定指向一個double值
}  
//相反,指針則應該總是被測試,防止其為空:
void printDouble(const double *pd)
{
if (pd)
{ // 檢查是否為NULL
 cout << *pd;
}
}
           

指針與引用的另一個重要的不同是指針可以被重新指派以指向另一個不同的對象。但是引用則總是指向在初始化時被指定的對象,以後不能改變。

string s1("Nancy");
string s2("Clancy");
string &rs = s1; // rs 引用 s1
string *ps = &s1; // ps 指向 s1
rs = s2; // rs 仍舊引用s1,
// 但是 s1的值現在是"Clancy",s1被更改,但是s2沒有改變
ps = &s2; // ps 現在指向 s2;指針隻是換換指向而已,并沒有對記憶體單元中的值進行操作
//s1 沒有改變
           

總的來說,在以下情況下你應該使用指針,一是你考慮到存在不指向任何對象的可能(在這種情況下,你能夠設定指針為空),二是你需要能夠在不同的時刻指向不同的對象(在這種情況下,你能改變指針的指向)。如果總是指向一個對象并且一旦指向一個對象後就不會改變指向,那麼你應該使用引用。

還有一種情況,就是當你重載某個操作符時,你應該使用引用。最普通的例子是操作符[].這個操作符典型的用法是傳回一個目标對象,其能被指派。

vector<int> v(); // 建立整形向量(vector),大小為10;
v[] = ; // 這個被指派的目标對象就是操作符[]傳回的值
//如果操作符[]傳回一個指針,那麼後一個語句就得這樣寫:
*v[] = ; //此時隻是為了說明問題而寫的,編譯器不一定能通過,有語義誤解
// 但是這樣會使得v看上去象是一個向量指針。是以你會選擇讓操作符傳回一個引用。
           

當你知道你必須指向一個對象并且不想改變其指向時,或者在重載操作符并為防止不必要的語義誤解時,你不應該使用指針。而在除此之外的其他情況下,則應使用指針假設你有

void func(int* p, int&r);
int a =;
int b =;
func(&a,b);

//指針本身的值(位址值)是以值傳遞進行的,你能改變位址值,但這并不會改變指針所指向的變量的值,
p = someotherpointer;//a is still 1

//但能用指針來改變指針所指向的變量的值,
*p =; // a now is 123131

//但引用本身是以引用傳遞進行的,改變其值即改變引用所對應的變量的值
r =;// b now is 1231

//盡可能使用引用,不得已時使用指針。
           

當你不需要“重新指向”時,引用一般優先于指針被選用。這通常意味着引用用于類的公有接口時更有用。引用出現的典型場合是對象的表面,而指針用于對象内部。

上述的例外情況是函數的參數或傳回值需要一個“臨界”的引用時。這時通常最好傳回/擷取一個指針,并使用 NULL 指針來完成這個特殊的使命。(引用應該總是對象的别名,而不是被解除引用的NULL 指針)。

注意:由于在調用者的代碼處,無法提供清晰的的引用語義,是以傳統的 C 程式員有時并不喜歡引用。然而,當有了一些 C++ 經驗後,你會很快認識到這是資訊隐藏的一種形式,它是有益的而不是有害的。就如同,程式員應該針對要解決的問題寫代碼,而不是機器本身。

通過以上分析,本人認為:能使用引用的地方都能使用指針,反過來不行。

參考:http://blog.csdn.net/thisispan/article/details/7456169#cpp

繼續閱讀