亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

深入解析C++中的引用類型

2020-01-26 15:55:04
字體:
來源:轉載
供稿:網友

c++比起c來除了多了類類型外還多出一種類型:引用。這個東西變量不象變量,指針不象指針,我以前對它不太懂,看程序時碰到引用都稀里糊涂蒙過去。最近把引用好好地揣摩了一番,小有收獲,特公之于社區,讓初學者們共享。

引用指的是對一個對象的引用。那么什么是對象?在c++中狹義的對象指的是用類,結構,聯合等復雜數據類型來聲明的變量,如 MyClass myclass,CDialog  mydlg,等等。廣義的對象還包括用int,char,float等簡單類型聲明的變量,如int a,char b等等。我在下文提到“對象”一詞全指的是廣義的對象。c++
的初學者們把這個廣義對象的概念建立起來,對看參考書是很有幫助的,因為大多數書上只顧用“對象”這個詞,對于這個詞還有廣義和狹義兩種概念卻只字不提。

一。引用的基本特性
首先讓我們聲明一個引用并使用它來初步認識引用。
例一:

復制代碼 代碼如下:

            int v,k,h;
            int &rv=v;
            rv=3;      //此時v的值也同時變成了3。
            v=5;
            k=rv+2;    //此時k=5+2=7。
            h=12;
            rv=h;
            rv=20;

第1句聲明了三個對象(簡單變量)。

第2句的意思是:聲明了一個引用,名字叫rv,它具有int類型,或者說它是對int類型的引用,而且它被初始化為與int類型的對象v“綁定”在一起。此時rv叫做對象v的引用。

第3句把rv的值賦為3。引用的神奇之處就在這里,改變引用的值的同時也改變了和引用所綁定在一起的對象的值。所以此時v的值也變成了3。

第4句把v的值改為5,此時指向v的引用的值也被改成了5。所以第5句的中k的值是5+2等于7。

上述5句說明了引用及其綁定的對象的關系:在數值上它們是聯動的,改變你也就改變了我,改變我也就改變了你。事實上,訪問對象和訪問對象的引用,就是訪問同一塊內存區域。

第6,7,8三句說明了引用的另一個特性:從一而終。什么意思?當你在引用的聲明語句里把一個引用綁定到某個對象后,這個引用就永遠只能和這個對象綁定在一起了,沒法改了。所以這也是我用了“綁定”一詞的原因。而指針不一樣。當在指針的聲明語句里把指針初始化為指向某個對象后,這個指針在將來如有需要還可以改指別的對象。因此,在第7句里把rv賦值為h,并不意味著這個引用rv被重新綁定到了h。事實上,第7句只是一條簡單的賦值語句,執行完后,rv和v的值都變成了12。第8句執行完后,rv和v的值都是20,而h保持12不變。

引用還有一個特性:聲明時必須初始化,既必須指明把引用綁定到什么對象上。大家知道指針在聲明時可以先不初始化,引用不行。所以下列語句將無法通過編譯:

復制代碼 代碼如下:

       int v;
              int &rv;
              rv=v;

再舉一例:
例二:
復制代碼 代碼如下:

          class MyClass
          {
              public:
                  int a;
                  ...
                  ...
          };

          MyClass  myclass;
          Myclass& cc=myclass;
          myclass.a=20;          //等價于cc.a=20
          cc.a=60;               //等價于myclass.a=60


從以上例子可以看到,無論這個對象有多復雜,使用該對象的引用或是使用該對象本身,在語法格式上是一樣的,在本質上我們都使用了內存中的同一塊區域。

取一個引用的地址和取一個對象的地址的語法是一樣的,都是用取地址操作符"&"。例如:

復制代碼 代碼如下:

          int i;
          int &ri;
          int *pi=&ri;//這句的作用和int *pi=&i是一樣的。

當然了,取一個對象的地址和取這個對象的引用的地址,所得結果是一樣的。

二。引用在函數參數傳遞中的作用
現在讓我們通過函數參數的傳遞機制來進一步認識引用。在c++中給一個函數傳遞參數有三種方法:1,傳遞對象本身。2,傳遞指向對象的指針。3,傳遞對象的引用。

例三:

復制代碼 代碼如下:

          class MyClass
          {
              public:
                  int a;
                  void method();
          };

          MyClass  myclass;

          void fun1(MyClass);
          void fun2(MyClass*);
          void fun3(MyClass&);

          fun1(myclass);     //執行完函數調用后,myclass.a=20不變。
          fun2(&myclass);    //執行完函數調用后,myclass.a=60,改變了。

          fun3(myclass);     //執行完函數調用后,myclass.a=80,改變了。

          //注意fun1和fun3的實參,再次證明了:使用對象和使用對象的引用,在語法格式上是一樣的。

          void fun1(MyClass mc)
          {
                mc.a=40;
                mc.method();
          }

          void fun2(MyClass* mc)
          {
                mc->a=60;
                mc->method();
          }

          void fun3(MyClass& mc)
          {
                mc.a=80;
                mc.method();
          }


我們有了一個MyClass類型的對象myclass和三個函數fun1,fun2,fun3,這三個函數分別要求以對象本身為參數;以指向對象的指針為參數;以對象的引用為參數。

請看fun1函數,它使用對象本身作為參數,這種傳遞參數的方式叫傳值方式。c++將生成myclass對象的一個拷貝,把這個拷貝傳遞給fun1函數。在fun1函數內部修改了mc的成員變量a,實際上是修改這個拷貝的成員變量a,絲毫影響不到作為實參的myclass的成員變量a。

fun2函數使用指向MyClass類型的指針作為參數。在這個函數內部修改了mc所指向的對象的成員變量a,這實際上修改的是myclass對象的成員變量a。

fun3使用myclass對象的引用作為參數,這叫傳引用方式。在函數內部修改了mc的成員變量a,由于前面說過,訪問一個對象和訪問該對象的引用,實際上是訪問同一塊內存區域,因此這將直接修改myclass的成員變量a。

從fun1和fun3的函數體也可看出,使用對象和使用對象的引用,在語法格式上是一樣的。

在fun1中c++將把實參的一個拷貝傳遞給形參。因此如果實參占內存很大,那么在參數傳遞中的系統開銷將很大。而在fun2和fun3中,無論是傳遞實參的指針和實參的引用,都只傳遞實參的地址給形參,充其量也就是四個字節,系統開銷很小。

三。返回引用的函數
引用還有一個很有用的特性:如果一個函數返回的是一個引用類型,那么該函數可以被當作左值使用。什么是左值搞不懂先別管,只需了解:如果一個對象或表達式可以放在賦值號的左邊,那么這個對象和表達式就叫左值。

舉一個雖然無用但很說明問題的例子:
例四:

復制代碼 代碼如下:

             int i;
             int& f1(int&);
             int  f2(int);
             f1(i)=3;
             f2(i)=4;

                int& f1(int&i)
                {
                   return i;
                }

                int f2(int i)
                {
                   return i;
                }


試試編譯一下,你會發現第4句是對的,第5句是錯的。對這個例子而言,i的引用被傳遞給了f1,然后f1把這個引用原樣返回,第4句的意義和i=3是一樣的。

查了查書,引用的這個特性在重載操作符時用得比較多。但是我對重載操作符還是稀里糊涂,所以就舉不出例子了。
強調一個小問題,看看如下代碼有何錯誤:

復制代碼 代碼如下:

                int &f1();

                f1()=5;
                ...
                ...
                int &f1()
                {
                    int i;
                    int &ri=i;
                    return ri;
                }

注意函數f1返回的引用ri是在函數體內聲明的,一旦函數返回后,超出了函數作用域,ri所指向的內存區域,即對象i所占據的內存區域就被收回了,再對這片內存區域賦值會出錯的。

四。引用的轉換
前面所舉的例子,引用的類型都是int類型,并且這些引用都被初始化為綁定到int類型的對象。那么我們設想是否可以聲明一個引用,它具有int類型,卻被初始化綁定到一個float類型的對象?如下列代碼所示:
float f;
int &rv=f;

結果證明這樣的轉換不能通過msvc++6.0的編譯。但是引用的轉換并非完全不可能,事實上一個基類類型的引用可以被初始化綁定到派生類對象,只要滿足這兩個條件:
1,指定的基類是可訪問的。
2,轉換是無二義性的。

舉個例子: 例五:

復制代碼 代碼如下:

          class A
          {
            public:
                int a;
          };
          class B:public A
          {
           public:
                int b;
          };
          A Oa;
          B Ob;
          A& mm=Ob;
          mm.a=3;

我們有一個基類A和派生類B,并且有一個基類對象Oa和派生類對象Ob,我們還聲明了一個引用mm,它具有基類類型但被綁定到派生類對象Ob上。由于我們的這兩個類都很簡單,滿足那兩個條件,因此這段代碼是合法的。在這個例子中,mm和派生類Ob中的基類子對象是共用一段內存單元的。所以,語句mm.a=3相當于Ob.a=3,但是表達式mm.b卻是不合法的,因為基類子對象并不包括派生類的成員。

五。總結
最后把引用給總結一下:
1。對象和對象的引用在某種意義上是一個東西,訪問對象和訪問對象的引用其實訪問的是同一塊內存區。

2。使用對象和使用對象的引用在語法格式上是一樣的。

3。引用必須初始化。

4。引用在初始化中被綁定到某個對象上后,將只能永遠綁定這個對象。

5?;愵愋偷囊每梢员唤壎ǖ皆摶惖呐缮悓ο?,只要基類和派生類滿足上文提到的兩個條件   。這時, 該引用其實是派生類對象中的基類子對象的引用。

6。用傳遞引用的方式給函數傳遞一個對象的引用時,只傳遞了該對象的地址,系統消耗較小。在函數體內訪問    形參,實際是訪問了這個作為實參的對象。

7。一個函數如果返回引用,那么函數調用表達式可以作為左值。

六。其他
1。本文中的代碼在msvc++6.0中調試驗證過。
2。第四節“引用的轉換”中的例子:
float f;
int &rv=f;

查看bc++3.1的資料,據說是合法的。此時編譯器生成了一個float類型的臨時
對象,引用rv被綁定到了這個臨時對象上,就是說,此時rv并不是f的引用。不知
道bc++3.1里的這個特性有什么用。

3??梢栽趍svc++6.0里聲明這樣的引用:
const int &rv=3;

此時rv的值就是3,而且無法更改。這可能沒有有什么用。因為如果我們要使
用一個符號來代表常數的話,有的是更常見的方法:
#define rv 3

4。把第四節中的例子稍稍修改一下:
float f;
int &rv=(int&)f;

這時就可以通過msvc++6.0的編譯了。此時rv被綁定到了f上,rv和f共用一片存儲區。不過由于引用rv的類型是int,所以通過rv去訪問這片存儲區時,存儲區的內容被解釋為整數;通過f去訪問這片存儲區時,存儲區的內容被解釋為實數。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩国产欧美精品一区二区三区| 91精品国产高清自在线看超| 久久久国产视频91| 国内精品免费午夜毛片| 国产成人精品在线播放| 国产精品久久久久久久一区探花| 综合网日日天干夜夜久久| 久久精品男人天堂| 国内精品国产三级国产在线专| 国产精品91久久久| 欧美在线欧美在线| 欧美日韩成人精品| 日韩在线资源网| 亚洲在线免费观看| 久久精品国产96久久久香蕉| 亚洲国产成人在线播放| 日本中文字幕久久看| 国产亚洲精品va在线观看| 992tv在线成人免费观看| 中文字幕欧美日韩va免费视频| 欧美精品在线观看| 亚洲国产精品资源| 欧美极品欧美精品欧美视频| 国产精品久久久久影院日本| 国产一区二区丝袜| 久久久久一本一区二区青青蜜月| 69影院欧美专区视频| 91a在线视频| 欧美激情aaaa| 成人午夜小视频| 欧美性猛交xxxx富婆| 成人免费网视频| 国产午夜精品全部视频播放| 国产精国产精品| 久久久日本电影| www.亚洲一二| 欧美激情啊啊啊| 亚洲精品久久久久久久久| 亚洲一区免费网站| 亚洲成在人线av| 欧美第一黄网免费网站| 久久亚洲影音av资源网| 在线观看视频99| 国产区亚洲区欧美区| 国产日韩欧美自拍| 97国产一区二区精品久久呦| 国产狼人综合免费视频| 欧日韩不卡在线视频| 日韩高清有码在线| 久久久久久91| 欧美超级乱淫片喷水| 91精品久久久久久久久久| 日韩电影在线观看中文字幕| 国产999精品久久久影片官网| 欧美成人在线免费| 国产一区二区三区丝袜| 亚洲精品视频播放| 国产精品极品在线| 欧美性猛交xxxx乱大交3| 亚洲va码欧洲m码| 黑人极品videos精品欧美裸| 51久久精品夜色国产麻豆| 欧美xxxx18国产| 中文字幕亚洲欧美日韩在线不卡| 亚洲成人精品视频在线观看| 久久69精品久久久久久国产越南| 国产精品麻豆va在线播放| 中文字幕亚洲情99在线| 欧美激情欧美激情在线五月| 欧美日韩一区二区三区在线免费观看| 黄色一区二区在线观看| 亚州欧美日韩中文视频| 久久精品视频99| 国产精品wwww| 精品久久久久久电影| 欧美成人精品一区| 国产一区二区久久精品| 俺去亚洲欧洲欧美日韩| 国产女人18毛片水18精品| 57pao国产成人免费| 久久久久久久久久亚洲| 成人精品福利视频| 欧美性色视频在线| 欧美大片欧美激情性色a∨久久| 日韩成人av在线播放| 久久久亚洲网站| 岛国视频午夜一区免费在线观看| 欧美综合在线观看| 久久精品成人欧美大片| 国产精品自拍网| 中日韩美女免费视频网站在线观看| 亚洲福利在线看| 久久久亚洲欧洲日产国码aⅴ| 91精品国产高清久久久久久91| 亚洲三级av在线| 成人网页在线免费观看| 亚洲一区二区三区四区在线播放| 日韩电影中文字幕av| 深夜福利91大全| 欧美国产日韩xxxxx| 久久成年人免费电影| 91系列在线播放| 亚洲欧美一区二区三区情侣bbw| 国产精品久久久久国产a级| 国产日韩av在线播放| 亚洲成av人片在线观看香蕉| 欧美亚洲成人免费| 国产啪精品视频| 色伦专区97中文字幕| 国产99久久精品一区二区永久免费| 亚洲美女av电影| 亚洲精品视频中文字幕| 亚洲图片欧美日产| 久久国产视频网站| 久久综合色88| 91高潮在线观看| 欧美激情按摩在线| 51精品国产黑色丝袜高跟鞋| 亚洲第一二三四五区| 亚洲综合精品伊人久久| 4438全国亚洲精品在线观看视频| 欧美人与性动交a欧美精品| 日韩人在线观看| 欧美日韩电影在线观看| 最近中文字幕mv在线一区二区三区四区| 国产日韩亚洲欧美| 亚洲久久久久久久久久久| 久久伊人免费视频| 爽爽爽爽爽爽爽成人免费观看| 欧美极品少妇xxxxⅹ免费视频| 国产午夜精品美女视频明星a级| 欧美精品电影免费在线观看| 欧美日韩中国免费专区在线看| 国产精品高潮呻吟视频| 在线观看视频亚洲| 国产一区二区丝袜| 亚洲国产精品人久久电影| 久久亚洲精品国产亚洲老地址| 精品成人国产在线观看男人呻吟| 91国内揄拍国内精品对白| 亚洲人成毛片在线播放| 日本不卡免费高清视频| 清纯唯美亚洲综合| 在线日韩欧美视频| 欧美理论电影在线观看| 91精品久久久久久久久久久| 亚洲日本成人女熟在线观看| 欧美激情精品久久久久久久变态| 热久久美女精品天天吊色| 日韩精品亚洲视频| 亚洲一区二区三区在线免费观看| 国产一区二区三区在线观看网站| 国产成人拍精品视频午夜网站| 伦理中文字幕亚洲| 亚洲成人免费在线视频| 欧美一级高清免费| 亚洲精品黄网在线观看| 日韩精品在线第一页| 欧美猛交ⅹxxx乱大交视频| 成人黄色av网站| 国产91在线视频| 色偷偷偷亚洲综合网另类| 最近2019好看的中文字幕免费| 国产精品视频网址|