(搬家文) c++引用深入探讨
(偶然翻起自己的舊博,忽然發現大三的時候寫的這篇文章,仔細看看覺得寫的還是那么回事,所以趕緊搭救出來)
引用的聲明:?? 基本格式:引用類型 &引用名=被引用對象?
引用的使用:引用可以被當作被引用對象的別名使用,單純的引用是無意義的,引用主要應用于四個方面:
?引用的深入探討:現在開始進入正題
??? 1.引用占內存空間嗎?
??????? 如果引用只是一個別名的話 他不應該占有內存空間 我用下面這段代碼來查看
?
代碼 #include?<iostream>using?namespace?std;
void?fa(){
????int?a[4];????
????cout<<a<<endl;
}
void?fb(){
????int?a[4];
????int?&b=a[0];
????cout<<a<<endl;
????fa();
}
void?fc(){
????int?a[4];
????cout<<a<<endl;
????fb();
}
int?main()
{
????fc();
????getchar();
????return?0;
}
?
?
這段代碼里 我用了三個嵌套的函數調用 這樣 fa 和fc的棧段就把fb夾在了中間 fb的棧段大小變化的話 會導致fc中a的地址偏移 但是并不是每個分配都會導致棧段增大的 所以應該先測試一下 確定a的合適大小 使得一旦聲明變量 b的棧段就增大。
把int?&b=a[0];注釋掉的話 可以看到fc中輸出的地址變了 fb沒有變 那么 引用b顯然占據了內存空間 我的代碼在g++中編譯,結果也是g++的結果。
2.引用的值不可改變嗎?
一個已經初始化的引用類型對象 其引用的對象不可能被合法的改變。
前面一段代碼展示給我們 引用確實占據了內存空間 ,了進一步了解其本質,我們必須獲得它的地址。&取地址操作符顯然是無法做到的 幾乎每個學c++的人都會嘗試用這種辦法去取引用類型的地址,但得到的都是被引用對象的地址。
還從前面的例子入手 fb中 a的地址沒有改變? fa中a的地址改變 那么 int &b的分配應該在 二者之間 于是 最可能的位置就是a中的a[4]?? 但輸出之后我發現a[4]不是,因為數組a是跟棧逆向分配的 之后我試了這樣的代碼
void fb(){
??? int a[4];
??? int b=20;
??? cout<<a[-1]<<endl;
??? fa();
}
?在我的編譯器中 b跟a[-1]總是相等 于是 我把int b 替換成int &b=a[0]; ok 我發現它指向了一個貌似地址的東西。改變b的指向 發現a[-1]是隨之變化的 現在 我幾乎可以確定 a[-1]就是b了 再用一段這樣的代碼來檢驗
void fb(){
??? int a[4]={1,2,3,4};
??? int &b=a[0];
??? a[-1]+=4;
??? cout<<b<<","<<a[0]<<endl;
??? fa();
}
引用真的是不可改變的嗎? 在這個例子中 我使b指向了a[1] 而不再是a[0]
3.引用和指針
從上面的例子看出 引用的內部實現和指針并無兩樣。如果參考其他語言的思想的話 可以得到結論:引用就是指針常量。 在c++中 引用在語法上與指針有著明顯的差異 但是 他們并沒有本質不同 引用是c++中實現的一種限制比較嚴格的常量指針 它在參與任何運算之前自動解引用。
在使用中 推薦盡量用引用代替指針,因為引用是一種比指針更安全的類型 并且有更清晰的語義(當然指針也有適合的語義)
4.其他語言
順便一提,在C家的其他語言中 引用幾乎被作為訪問對象的唯一手段
C++:有指針 所有運算符會解引用 所有對象不作為引用 傳遞參數和返回值時如果不希望復制 則必須將形參指定為引用類型
C#:?unsafe模式有指針 除了=之外的操作符會解引用 所有對象作為引用 傳遞參數和返回值時如果希望復制 則必須顯式clone
Java:無指針 除了=之外的操作符會解引用 類似c#
javascript:無指針但是可以變通 除了=之外的操作符會解引用?沒有提供復制傳遞的方法(郁悶)
轉載于:https://www.cnblogs.com/winter-cn/archive/2010/07/15/1777668.html
總結
以上是生活随笔為你收集整理的(搬家文) c++引用深入探讨的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: .NET平台依赖注入机制及IoC的设计与
- 下一篇: C++设计模式之工厂模式(1)