深入分析C++引用
????? 關(guān)于引用和指針的差別的文章非常多非常多,可是總是找不到他們的根本差別,偶然在codeproject上看到這篇文章,認(rèn)為講的挺好的,
所以翻譯了下,希望對(duì)大家有幫助。
原文地址: http://www.codeproject.com/KB/cpp/References_in_c__.aspx
?
引言
????? 我選擇寫(xiě) C++ 中的引用是由于我感覺(jué)大多數(shù)人誤解了引用。而我之所以有這個(gè)感受是由于我主持過(guò)非常多 C++ 的面試,而且我非常少?gòu)拿嬖囌咧械玫疥P(guān)于 C++ 引用的正確答案。
?????? 那么 c++ 中引用究竟意味這什么呢?通常一個(gè)引用讓人想到是一個(gè)引用的變量的別名,而我討厭將 c++ 中引用定義為變量的別名。這篇文章中,我將盡量解釋清楚, c++ 中根本就沒(méi)有什么叫做別名的東東。
?
背景
在 c/c++ 中,訪問(wèn)一個(gè)變量?jī)H僅能通過(guò)兩種方式被訪問(wèn),傳遞,或者查詢。這兩種方式是:
1. 通過(guò)值 訪問(wèn) / 傳遞變量
2. 通過(guò)地址 訪問(wèn) / 傳遞變量 – 這樣的方法就是指針
?
???? ? 除此之外沒(méi)有第三種訪問(wèn)和傳遞變量值的方法。引用變量也就是個(gè)指針變量,它也擁有內(nèi)存空間。最關(guān)鍵的是引用是一種會(huì)被編譯器自己主動(dòng)解引用的指針。非常難相信么?讓我們來(lái)看看吧。。。
?
以下是一段使用引用的簡(jiǎn)單 c++ 代碼
?#include <iostream.h> int main() { int i = 10; // A simple integer variable int &j = i; // A Reference to the variable i j++; // Incrementing j will increment both i and j. // check by printing values of i and j cout<< i << j <<endl; // should print 11 11 // Now try to print the address of both variables i and j cout<< &i << &j <<endl; // surprisingly both print the same address and make us feel that they are // alias to the same memory location. // In example below we will see what is the reality return 0; }?
?
引用事實(shí)上就是 c++ 中的常量指針。表達(dá)式 ? int &i = j; 將會(huì)被編譯器轉(zhuǎn)化成 int *const i = &j; 而引用之所以要初始化是由于 const 類(lèi)型變量必須初始化,這個(gè)指針也必須有所指。以下我們?cè)俅尉劢沟缴厦孢@段代碼,并使用編譯器的那套語(yǔ)法將引用替換掉。
?
#include <iostream.h> int main() { int i = 10; // A simple integer variable int *const j = &i; // A Reference to the variable i (*j)++; // Incrementing j. Since reference variables are // automatically dereferenced by compiler // check by printing values of i and j cout<< i << *j <<endl; // should print 11 11 // A * is appended before j because it used to be reference variable // and it should get automatically dereferenced. return 0; }
?
??? 讀者一定非常奇怪為什么我上面這段代碼會(huì)跳過(guò)打印地址這步。這里須要一些解釋。由于引用變量時(shí)會(huì)被編譯器自己主動(dòng)解引用的,那么一個(gè)諸如 ? cout << &j << endl; 的語(yǔ)句,編譯器就會(huì)將其轉(zhuǎn)化成語(yǔ)句 ? cout << &*j << endl; ? 如今 &* 會(huì)相互抵消,這句話變的毫無(wú)意義,而 cout 打印的 j 值就是 i 的地址,由于其定義語(yǔ)句為 int *const j = &i;
?
????? 所以語(yǔ)句 cout << &i << &j << endl; 變成了 cout << &i << &*j << endl; 這兩種情況都是打印輸出 i 的地址。這就是當(dāng)我們打印普通變量和引用變量的時(shí)候會(huì)輸出同樣地址的原因。
?
????? 以下給出一段復(fù)雜一些的代碼,來(lái)看看引用在級(jí)聯(lián) (cascading) 中是怎樣運(yùn)作的。
?
#include <iostream.h> int main() { int i = 10; // A Simple Integer variable int &j = i; // A Reference to the variable // Now we can also create a reference to reference variable. int &k = j; // A reference to a reference variable // Similarly we can also create another reference to the reference variable k int &l = k; // A reference to a reference to a reference variable. // Now if we increment any one of them the effect will be visible on all the // variables. // First print original values // The print should be 10,10,10,10 cout<< i << "," << j << "," << k << "," << l <<endl; // increment variable j j++; // The print should be 11,11,11,11 cout<< i << "," << j << "," << k << "," << l <<endl; // increment variable k k++; // The print should be 12,12,12,12 cout<< i << "," << j << "," << k << "," << l <<endl; // increment variable l l++; // The print should be 13,13,13,13 cout<< i << "," << j << "," << k << "," << l <<endl; return 0; }
?
以下這段代碼是將上面代碼中的引用替換之后代碼,也就是說(shuō)明我們不依賴編譯器的自己主動(dòng)替換功能,手動(dòng)進(jìn)行替換也能達(dá)到同樣的目標(biāo)。
?
#include <iostream.h> int main() { int i = 10; // A Simple Integer variable int *const j = &i; // A Reference to the variable // The variable j will hold the address of i // Now we can also create a reference to reference variable. int *const k = &*j; // A reference to a reference variable // The variable k will also hold the address of i because j // is a reference variable and // it gets auto dereferenced. After & and * cancels each other // k will hold the value of // j which it nothing but address of i // Similarly we can also create another reference to the reference variable k int *const l = &*k; // A reference to a reference to a reference variable. // The variable l will also hold address of i because k holds address of i after // & and * cancels each other. // so we have seen that all the reference variable will actually holds the same // variable address. // Now if we increment any one of them the effect will be visible on all the // variables. // First print original values. The reference variables will have * prefixed because // these variables gets automatically dereferenced. // The print should be 10,10,10,10 cout<< i << "," << *j << "," << *k << "," << *l <<endl; // increment variable j (*j)++; // The print should be 11,11,11,11 cout<< i << "," << *j << "," << *k << "," << *l <<endl; // increment variable k (*k)++; // The print should be 12,12,12,12 cout<< i << "," << *j << "," << *k << "," << *l <<endl; // increment variable l (*l)++; // The print should be 13,13,13,13 cout << i << "," << *j << "," << *k << "," << *l <<endl; return 0; }
?
???????? 我們通過(guò)以下代碼能夠證明 c++ 的引用不是神馬別名,它也會(huì)占用內(nèi)存空間的。
#include <iostream.h> class Test { int &i; // int *const i; int &j; // int *const j; int &k; // int *const k; }; int main() { // This will print 12 i.e. size of 3 pointers cout<< "size of class Test = " << sizeof(class Test) <<endl; return 0; }
?
?
結(jié)論
我希望這篇文章能把 c++ 引用的全部東東都解釋清楚,然而我要指出的是 c++ 標(biāo)準(zhǔn)并沒(méi)有解釋編譯器怎樣實(shí)現(xiàn)引用的行為。所以實(shí)現(xiàn)取決于編譯器,而大多數(shù)情況下就是將事實(shí)上現(xiàn)為一個(gè) const 指針。
?
?
引用支持 c++ 虛函數(shù)機(jī)制的代碼
?
#include <iostream.h> class A { public: virtual void print() { cout<<"A.."<<endl; } }; class B : public A { public: virtual void print() { cout<<"B.."<<endl; } }; class C : public B { public: virtual void print() { cout<<"C.."<<endl; } }; int main() { C c1; A &a1 = c1; a1.print(); // prints C A a2 = c1; a2.print(); // prints A return 0; }
?
?
上述代碼使用引用支持虛函數(shù)機(jī)制。假設(shè)引用不過(guò)一個(gè)別名,那怎樣實(shí)現(xiàn)虛函數(shù)機(jī)制,而虛函數(shù)機(jī)制所須要的動(dòng)態(tài)信息只能通過(guò)指針才干實(shí)現(xiàn),所以更加說(shuō)明引用事實(shí)上就是一個(gè) const 指針。
轉(zhuǎn)載于:https://www.cnblogs.com/bhlsheji/p/4232061.html
總結(jié)
- 上一篇: 新快现类似产品_小米全新折叠屏产品曝光,
- 下一篇: c++ 可视化界面_这些算法可视化网站助