青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

posts - 200, comments - 8, trackbacks - 0, articles - 0

左值和右值(轉)

Posted on 2012-12-16 15:08 鑫龍 閱讀(332) 評論(0)  編輯 收藏 引用 所屬分類: c++

左值右值

左值(lvalue)和右值(rvalue)是編程中兩個非常基本的概念,但是也非常容易讓人誤解,看了很多文章,自我感覺真正將這個問題講的很透徹的文章還沒有看見,所以自告奮勇來嘗試一下。如果左值右值的概念不是非常清楚的話,它們遲早會像攔路虎一樣跳出來,讓你煩心不已,就像玩電腦游戲的時候每隔一段時間總有那么幾個地雷考驗你的耐性,如果一次把所有地雷掃盡就好了。:)

左值(lvalue)和右值(rvalue)最先來源于編譯理論(感謝南大小百合的programs)。在C語言中表示位于賦值運算符兩側的兩個值,左邊的就叫左值,右邊的就叫右值。比如:

int ii = 5;//ii是左值,5是右值

int jj = ii;//jj是左值,ii是右值

上面表明,左值肯定可以作為右值使用,但反之則不然。左值和右值的最早區別就在于能否改變。左值是可以變的,右值不能變。【注1

1:這一點在C++中已經豬羊變色,不再成立。拱豬游戲還是挺好玩的,我還真抓過好幾次全紅心,不過真的好險。:)

在很多文章中提到,在C++中,左值更多的指的是可以定位,即有地址的值,而右值沒有地址。【注2

2:這一點仍然不準確,我在程序中生成一個臨時右值std::vector(),你能夠說它沒有地址嗎?難道它是沒有肉體的鬼魂或幽靈?它是有地址的,而且它也是絕對的右值。

在現代C++中,現在左值和右值基本上已經失去它們原本所具有的意義,對于左值表達式,通過具體名字和引用(pointer or reference)來指定一個對象。非左值就是右值。我來下一個定義:

左值表示程序中必須有一個特定的名字引用到這個值。

右值表示程序中沒有一個特定的名字引用到這個值。

跟它們是否可以改變,是否在棧或堆(stack or heap)中有地址毫無關系。

1.左值

在下面的代碼中:

int ii = 5;

int const jj = ii;

int a[5];

a[0] = 100;

*(a+3) = 200;

int const& max( int const& a, int const& b ) //call by reference

{

      return a > b ? a : b;

}

int& fun(int& a) //call by reference

{

      a += 5;

   return a;

}

iijja[0]*(a+3),還有函數max的返回值比如max(ii, jj),【注3】函數fun的返回值fun(ii)都是左值。,它們都是有特定的引用名字的值。iijja[0]*(a+3)max(ii, jj)fun(ii)分別就是它們的名字。

3:在這里有一個不太容易分清楚的盲點。那就是有人會問max(8, 9)到達是左值還是右值,C++標準規定常量引用(reference to const)可以引用到右值,所以max(8, 9)似乎應該是右值,不過不管它是左值,還是右值,我們都不能試圖去改變它。為了與前面的概念一致,我認為它是左值,不可改變的常量左值。

左值有不能改變的,即被const所修飾的左值,比如上面的jjmax(ii, jj)都是被常量(const)魔咒所困住的左值。

沒有被const困住的左值當然是可以改變的,比如下面的代碼都是成立的:

ii = 600;

a[0] = 700;

fun(ii) = 800; //OK!

我們的眼睛沒有問題,fun(ii) = 800;完全正確,因為它是可以改變的左值。所以我們看STL的源碼,就會理解std::vector中的重載operator[]運算符的返回值為什么要寫成引用,因為operator[]必須返回左值。

 

2.右值

沒有特定名字的值是右值。先看下面的代碼:

std::list();

std::string(“It is a rvalue!”);

int fun1() //call by value

{

      

}

int* fun2() //call by reference

{

      

}

其中std::list()std::string(“It is a rvalue!”),函數fun1的返回值fun1(),函數fun2的返回值fun2()都是右值,它們的值都沒有特定的名字去引用。也許有人會奇怪,fun2()也是右值?最前面的max(a,b)不是左值嗎?

請看清楚,函數fun2的返回值是pointerpointer也是call by value,而函數max的返回值是referencereferencecall by reference。所以說C++中引入reference不僅僅是為了方便,它也是一種必須。【注4

4Scott Meyer寫的《More Effective C++》的條款1專門講了pointerreference的區別,寫的很好,辨別的非常清楚。

fun2()是右值,但 *fun2()卻是左值,就跟經常看到的*p一樣,所以看C++庫代碼的時候,會發現重載operator*的函數返回值是reference

當然我還遺漏了一種右值,那就是字面上的(literal)值,比如58.23’a’等等理所當然的都是右值。

右值最初出現的時候,一個最大的特征就是不可改變。但就跟我們的道德標準一樣,時代不同了,標準也變化了,以前的三綱五常早已經被扔到歷史的垃圾堆里面了。

C++中有可以改變的右值,而且這個特性還非常有用。那就是用戶自定義的類(class)的構造函數生成的臨時對象。比如:

std::vector(9)std::deque(),……都是可以改變的右值。在Herb Sutter的《More Exceptional C++》中的條款7page51頁有這樣幾行代碼:

// Example 7-2(b): The right way to shrink-to-fit a vector.

vector<Customer> c( 10000 );

// ...now c.capacity() >= 10000...

// erase all but the first 10 elements

c.erase( c.begin()+10, c.end() );

// the following line does shrink c's

// internal buffer to fit (or close)

vector<Customer>( c ).swap( c );

// ...now c.capacity() == c.size(), or

// perhaps a little more than c.size()

認真看幾遍,你會發現但vector的大小增大到一定程度,你又用不著這么多空間的時候,你會想辦法把它收縮到最合適的大小,但利用別的辦法比如調用成員函數reserve()都無法辦到,這個時候就必須利用右值可以改變這個性質了。

vector<Customer>( c ).swap( c );這行代碼就是點睛之處。

首先使用復制構造函數生成臨時右值vector<Customer>( c ),這個右值正好是合適大小,然后和c交換【注5】,c就變成合適大小了,最后在整個表達式結束的時候,這個臨時右值析構歸還內存空間。真是紳士一般的優雅!

5:這個時候這個臨時右值就發生了改變。

如果還不理解,可以看看書,或者直接看庫的源代碼。

至于為什么會這樣?我思考了一下,我想是這樣的,我們看類(class)的數據布置結構,會發現它的每一個數據成員都是有名字的,我想編譯器在編譯的過程中,都會生成一個外部不所知的對這個臨時對象右值的名字引用,但需要改變這個臨時對象的時候,這個名字就用上了。比如:

class Point

{

public: //純粹為了方便,我把數據成員公開,現實中盡量不要這樣用

      int x, y ,z;

      ……//其他各種成員函數

};

我們現在就可以改變右值,用到了匿名的引用名字。

Point().x = 6;//改變了右值

Point().y = 6;//同意改變了右值,不過注意,這個右值跟上面的不是同一個。

總結

左值和右值的真正區別我想就是這些了,左值表示有特定的名字引用,而右值沒有特定的名字引用。當然我仍然會有疏忽,希望大家能夠提醒我,指正我的不足。

前兩天看Herb Sutter從郵件中寄來的新文章(我訂閱他的新文章郵件通知),一篇是講Tuple數據結構的,沒有什么新意,以前好像看過,還有一篇名字是:(MostlyPrivate,地址為http://www.cuj.com/documents/s=8273/cujcexp2107sutter/ 內容本身并不深,但看完文章,發現隨處可見C++的波詭云譎,又會對什么叫袖里乾坤,滴水藏海多一份感性認識。

在下一篇文章我想從不同于一般的角度,從自己的經歷談談在校畢業生在IT行業怎樣找工作,我想會讓所有讀者都有一些思考,不僅僅是求職者。題目我已經想好了,就叫《扮虎吃豬》,不過現在我有一些別的事情要忙,所以可能會讓大家等幾天。

轉載請注明來源,謝謝!

吳桐寫于2003.6.20

最近修改2003.6.21

轉自:
http://blog.csdn.net/csdnji/article/details/169200

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            极品少妇一区二区| 欧美电影免费观看高清完整版| 久久gogo国模裸体人体| 亚洲男人的天堂在线| 亚洲在线免费视频| 午夜免费电影一区在线观看| 午夜精品亚洲一区二区三区嫩草| 亚洲综合久久久久| 久久精品欧洲| 欧美国产激情二区三区| 亚洲精选中文字幕| 亚洲欧美日韩一区二区在线| 小处雏高清一区二区三区 | 中国成人亚色综合网站| 一区二区欧美日韩视频| 午夜精品久久久久久久99水蜜桃| 久久岛国电影| 欧美激情第9页| 国产精品久久久久久户外露出 | 免费日韩视频| 一本色道久久综合亚洲精品不| 亚洲一区二区精品在线| 久久精品理论片| 欧美日韩黄色一区二区| 亚洲男同1069视频| 欧美jizz19hd性欧美| 国产精品自拍视频| 亚洲日本一区二区| 久久精品一二三区| 亚洲日韩中文字幕在线播放| 一区二区三区国产在线| 久久久久久亚洲精品中文字幕 | 亚洲欧美美女| 欧美激情第五页| 欧美一区二区三区成人| 欧美色网一区二区| 亚洲黄色影院| 久久亚洲捆绑美女| 亚洲欧美日韩一区在线| 欧美日韩卡一卡二| 亚洲人成人77777线观看| 久久精选视频| 亚洲综合另类| 欧美午夜电影在线| 99视频精品在线| 欧美激情在线免费观看| 久久成人精品电影| 国产日韩在线看| 欧美一级视频精品观看| 在线视频日韩| 国产精品毛片大码女人| 亚洲天堂av图片| 亚洲免费电影在线| 欧美激情综合在线| 亚洲精品视频在线观看网站| 欧美成年人在线观看| 久久久五月婷婷| 在线精品视频一区二区| 另类av导航| 久久精品在线观看| 在线观看国产一区二区| 久久综合色婷婷| 久久野战av| 亚洲乱码国产乱码精品精天堂| 亚洲国产清纯| 欧美日韩另类一区| 亚洲天堂男人| 亚洲欧美日韩另类精品一区二区三区 | 一本色道久久综合亚洲精品高清| 欧美成人福利视频| 久久天天躁夜夜躁狠狠躁2022| 国内偷自视频区视频综合| 久久精品一区二区三区四区| 久久gogo国模裸体人体| 伊人伊人伊人久久| 亚洲电影一级黄| 欧美日韩伦理在线| 亚洲欧美在线一区| 久久不射中文字幕| 亚洲精品免费电影| 亚洲图片自拍偷拍| 国内外成人免费激情在线视频网站| 久久婷婷国产综合国色天香| 久热国产精品| 亚洲制服欧美中文字幕中文字幕| 午夜在线a亚洲v天堂网2018| 激情综合色丁香一区二区| 欧美黑人在线观看| 国产精品电影观看| 免费国产一区二区| 国产精品白丝黑袜喷水久久久| 欧美在线黄色| 欧美福利专区| 欧美在线三区| 欧美激情国产日韩精品一区18| 亚洲综合第一| 欧美成人午夜免费视在线看片 | 亚洲精品日韩激情在线电影| 国产精品亚洲综合天堂夜夜| 欧美成人精品1314www| 国产精品久久久999| 免费观看30秒视频久久| 国产精品久久久久久久第一福利| 欧美大片在线影院| 国产精品午夜国产小视频| 亚洲成色777777在线观看影院| 国产精品视频yy9099| 亚洲韩日在线| 一色屋精品视频免费看| 99这里只有精品| 亚洲日本成人| 久久精品国产99国产精品| 亚洲一区精品在线| 欧美激情精品久久久六区热门| 久久久亚洲国产天美传媒修理工| 欧美日韩在线播放一区| 亚洲国产精品久久久久秋霞影院| 国产视频一区二区在线观看 | 久久久久国产精品www| 一区二区三区四区五区视频| 久久精品亚洲一区二区| 亚洲一区二区三区四区在线观看| 麻豆久久婷婷| 久久综合给合| 国产日韩欧美中文在线播放| 99视频精品在线| 夜夜嗨一区二区三区| 欧美高清在线观看| 亚洲电影激情视频网站| 樱花yy私人影院亚洲| 久久精品网址| 久久香蕉国产线看观看网| 国产欧美91| 性做久久久久久免费观看欧美 | 欧美成人资源网| 精品电影在线观看| 久久精品99久久香蕉国产色戒| 午夜在线观看欧美| 国产精品久久久久9999高清| 一本色道久久综合亚洲91| 亚洲午夜一区| 国产精品日韩欧美一区二区| 亚洲一区亚洲| 久久国产日韩| 在线不卡免费欧美| 麻豆视频一区二区| 亚洲高清视频的网址| 亚洲精品专区| 欧美性大战xxxxx久久久| 亚洲线精品一区二区三区八戒| 亚洲欧洲av一区二区三区久久| 国产精品视频xxxx| 久久久久久久久岛国免费| 欧美国产日韩一二三区| 一区二区毛片| 国产亚洲精品自拍| 久久天堂成人| 一本一本a久久| 久久久www免费人成黑人精品| 黄色成人免费观看| 欧美激情二区三区| 亚洲一区三区在线观看| 蜜臀99久久精品久久久久久软件| 最新高清无码专区| 欧美日韩视频在线观看一区二区三区| 99视频有精品| 久久久久青草大香线综合精品| 亚洲国产导航| 欧美日韩精品是欧美日韩精品| 亚洲一区二区少妇| 欧美不卡高清| 亚洲欧美国产日韩天堂区| 国产亚洲一二三区| 欧美美女操人视频| 欧美在线在线| 99国产精品99久久久久久| 久久久久久网| 亚洲视频精品在线| 亚洲大胆av| 国产区日韩欧美| 欧美日韩精品免费看| 久久综合中文字幕| 午夜国产精品视频免费体验区| 欧美激情精品久久久六区热门 | 国产精品一区视频| 欧美不卡视频一区| 午夜精品剧场| 日韩午夜av在线| 免费在线欧美视频| 午夜日韩激情| 一本色道婷婷久久欧美| 在线精品亚洲| 国产日韩欧美视频| 欧美午夜影院| 欧美激情第1页| 免费视频久久| 久久久免费av| 久久久久久久久伊人| 翔田千里一区二区| 先锋影院在线亚洲|