都是位址的概念,引用的本質是指標常量
指標是乙個變數,這個變數所存的內容是乙個位址,指向記憶體的乙個儲存單元;而引用跟原來的變數實質上是同乙個東西,只不過是原變數的乙個別名而已,即引用是某塊記憶體的別名
指標可以有頂層const和底層const,而引用只有底層const。(引用的本質)
指標可以有多級,但是引用只能是一級(int **p;合法 而 int &&a是不合法的)
指標的值可以為空,但是引用的值不能為null,並且引用在定義的時候必須初始化;
指標的值在初始化後可以改變,即指向其它的儲存單元,而引用在進行初始化後就不會再改變了。(指標隨心所欲,引用一成不變)
「sizeof引用」得到的是所指向的變數(物件)的大小,而」sizeof指標」得到的是指標本身的大小;
指標和引用的自增(++)運算意義不一樣;
作為引數傳遞時有不同,建議用引用
摘自「moreeffective c++」
指標與引用,在moreeffective c++ 的條款一有詳細講述
條款一:指標與引用的區別
指標與引用看上去完全不同(指標用操作符『*』和『->』,引用使用操作符『&』),但是它們似乎有相同的功能。指標與引用都是讓你間接引用其他物件。你如何決定在什麼時候使用指標,在什麼時候使用引用呢?
首先,要認識到在任何情況下都不能用指向空值的引用。乙個引用必須總是指向某些物件。因此如果你使用乙個變數並讓它指向乙個物件,但是該變數在某些時候也可能不指向任何物件,這時你應該把變數宣告為指標,因為這樣你可以賦空值給該變數。相反,如果變數肯定指向乙個物件,例如你的設計不允許變數為空,這時你就可以把變數宣告為引用。
「但是,請等一下」,你懷疑地問,「這樣的**會產生什麼樣的後果?」
char *pc = 0;// 設定指標為空值
char& rc = *pc;// 讓引用指向空值
產生錯誤:引發了異常: 讀取訪問許可權衝突。rc 是 nullptr。(vs2017 32bits debug)
void printdouble(const
double& rd)
// 肯定指向乙個double值相反,指標則應該總是被測試,防止其為空:
void printdouble(const
double *pd)
}
string s1("nancy");
string s2("clancy");
string& rs = s1; // rs 引用 s1
string *ps = &s1; // ps 指向 s1
rs = s2; // rs 仍舊引用s1,
// 但是 s1的值現在是
// "clancy"
ps = &s2; // ps 現在指向 s2;
// s1 沒有改變
總的來說,在以下情況下你應該使用指標,一是你考慮到存在不指向任何物件的可能(在這種情況下,你能夠設定指標為空),二是你需要能夠在不同的時刻指向不同的物件(在這種情況下,你能改變指標的指向)。如果總是指向乙個物件並且一旦指向乙個物件後就不會改變指向,那麼你應該使用引用。
還有一種情況,就是當你過載某個操作符時,你應該使用引用。最普通的例子是操作符.這個操作符典型的用法是返回乙個目標物件,其能被賦值。
還有一種情況,就是當你過載某個操作符時,你應該使用引用。最普通的例子是操作符.這個操作符典型的用法是返回乙個目標物件,其能被賦值。
vector
v(10); // 建立整形向量(vector),大小為10;
// 向量是乙個在標準c庫中的乙個模板(見條款35)
v[5] = 10; // 這個被賦值的目標物件就是操作符返回的值
//如果操作符返回乙個指標,那麼後乙個語句就得這樣寫:
*v[5] = 10;
但是這樣會使得v看上去象是乙個向量指標。因此你會選擇讓操作符返回乙個引用。(這有乙個有趣的例外,參見條款30)
當你知道你必須指向乙個物件並且不想改變其指向時,或者在過載操作符並為防止不必要的語義誤解時,你不應該使用指標。而在除此之外的其他情況下,則應使用指標假設你有
void func(int* p, int&r);
int a =1;
int b =1;
func(&a,b);
指標本身的值(位址值)是以passby value進行的,你能改變位址值,但這並不會改變指標所指向的變數的值,
p = someotherpointer;//a is still 1
但能用指標來改變指標所指向的變數的值,
*p = 123131; // a now is 123131
但引用本身是以pass byreference進行的,改變其值即改變引用所對應的變數的值
r = 1231;// b now is 1231
盡可能使用引用,不得已時使用指標。
當你不需要「重新指向」時,引用一般優先於指標被選用。這通常意味著引用用於類的公有介面時更有用。引用出現的典型場合是物件的表面,而指標用於物件內部。
上述的例外情況是函式的引數或返回值需要乙個「臨界」的引用時。這時通常最好返回/獲取乙個指標,並使用 null 指標來完成這個特殊的使命。(引用應該總是物件的別名,而不是被解除引用的null 指標)。
注意:由於在呼叫者的**處,無法提供清晰的的引用語義,所以傳統的 c 程式設計師有時並不喜歡引用。然而,當有了一些 c++ 經驗後,你會很快認識到這是資訊隱藏的一種形式,它是有益的而不是有害的。就如同,程式設計師應該針對要解決的問題寫**,而不是機器本身。
參考文獻
c++引用與指標的區別(著重理解):
**c++中指標和引用的區別:
c++引用的本質:
指標引用和引用指標的區別
c 在傳參的過程中,指標 和指標引用 是有區別的。雖然,我們往往可以通過傳指標然後通過間址訪問來修改指標所指向物件的值,同樣,通過引用也可以直接修改物件的值。但是,當傳指標的時候有乙個問題,就是,我們雖然可以通過指標來修改指標所指向物件的值,但是我們沒有不能直接修改指標的內容 也就是指標變數存放的位...
傳指標和傳指標引用的區別 指標和引用的區別(本質)
指標傳遞引數本質上是值傳遞的方式,它所傳遞的是乙個位址值。值傳遞過程中,被調函式的形式引數作為被調函式的區域性變數處理,即在棧中開闢了記憶體空間以存放由主調函式放進來的實參的值,從而成為了實參的乙個副本。值傳遞的特點是被調函式對形式引數的任何操作都是作為區域性變數進行,不會影響主調函式的實參變數的值...
傳指標和傳指標引用的區別 指標和引用的區別(本質)
指標傳遞引數本質上是值傳遞的方式,它所傳遞的是乙個位址值。值傳遞過程中,被調函式的形式引數作為被調函式的區域性變數處理,即在棧中開闢了記憶體空間以存放由主調函式放進來的實參的值,從而成為了實參的乙個副本。值傳遞的特點是被調函式對形式引數的任何操作都是作為區域性變數進行,不會影響主調函式的實參變數的值...