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

大龍的博客

常用鏈接

統計

最新評論

關于NRV優化

    在C++中,函數返回整數或指針是通過eax寄存器進行傳遞的,理解起來比較簡單。

    但是返回對象或結構體一直是令人感到困惑的問題。今天我整理了一下,將整個返回過程寫下來,以作備用。

 

    還是先通過一個例子來理解這個問題:

首先,定義一個類Vector:

 

class Vector
{
public:
    int x,y;
};

 

然后定義函數add()對Vector對象進行操作:

Vector add(Vector& a, Vector & b)
{
    Vector v;
    v.x = a.x + b.x;
    v.y = a.y + b.y;
    return v;
}

 

現在的問題是:

如果調用如下語句:

Vector a, b;
Vector c = add(a, b);

請問從a, b傳入函數開始,一共創建了多少個對象?

 

在通常情況下我們會做出如下分析:

1. 在add()函數中創建對象v。

2. 函數返回,創建一個臨時變量__temp0,并將v的值拷貝到__temp0中。

3. 最后創建對象c,通過操作符=,將__temp0中的對象拷貝到c中。



 

但其實,我們會在后面看到,整個過程就只創建了1個對象:c。

 

為了更清晰的分析整個調用過程,我們為Vector加上默認構造函數和拷貝構造函數,并增加一個靜態變量count用于統計構造函數調用次數:

class Vector
{
public:
    static int count;

    static void init()
    {
        count = 0;
    }

    int x,y;

    Vector()
    {
        x = 0;
        y = 0;
        
        // For analysis.
        count ++;
        printf("Default Constructor was called.[0x%08x]\n", this);
    }

    Vector(const Vector & ref)
    {
        x = ref.x;
        y = ref.y;

        // For analysis.
        count ++;
        printf("Copy Constructor was called.[copy from 0x%08x to 0x%08x].\n", &ref, this);
    }

};

int Vector::count = 0;

 

然后在main()函數中寫上調用代碼:

    Vector a, b;
    Vector::init();
    printf("\n-- Test add() --\n");
    Vector c = add(a, b);
    printf("---- Constructors were called %d times. ----\n\n\n", Vector::count);

 

使用cl編譯。

(注:Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86, Microsoft (R) Incremental Linker Version 10.00.40219.01)

完成后,運行程序,得到如下結果:

-- Test add() --
Default Constructor was called.[0x0012fef8]
Copy Constructor was called.[copy from 0x0012fef8 to 0x0012ff60].
---- Constructors were called 2 times. ----

 

由此可知,在沒有優化的情況下,整個調用過程共創建了兩個對象:

即:c和__temp0.

 

整個調用過程偽代碼如下:

首先add()函數被編譯器看做:

void add(Vector& __result, Vector& a, Vector & b)
{
    __result.x = a.x + b.x;
    __result.y = a.y + b.y;
    return;
}

而調用代碼同時被修改為:

    Vector a, b;
    Vector::init();
    printf("\n-- Test add() --\n");
    Vector __temp0;        // 構造函數.
    add(__temp0, a, b);
    Vector c(__temp0);    // 拷貝構造函數.
    printf("---- Constructors were called %d times. ----\n\n\n", Vector::count);

 



 

現在就可以理解輸出結果了吧。

這里要強調一點,看到”=”并不等于調用了Operator=()的代碼,以下三種情況其實是等效的,都只調用了拷貝構造函數:

Vector b(a);
Vector b = a;
Vector b = Vector(a);

 

最精彩的部分在于,如果你用

cl /Ox

 

編譯代碼,使優化達到最大,再次運行,得到如下結果:

-- Test add() --
Default Constructor was called.[0x0012ff74]
---- Constructors were called 1 times. ----

 

這次,只調用了默認構造函數。這樣的修改被稱作Named Return Value(NRV) Optimization。

什么是NRV優化呢,顧名思義,就是保存返回值的變量不再使用沒名沒姓的__temp0這樣的東西了,而是直接把c作為返回變量,因此應該將NRV翻譯為“有名字的返回變量”吧,侯捷翻譯的《深入探索C++對象模型》居然把它稱為“具名數值”,真是不知所云。

言歸正傳,NVR優化的偽代碼如下:

    Vector c;
    add(c, a, b);

NVR優化的最大好處就是不會再去調用那次多余拷貝構造函數了(把__temp0拷貝到c),因此《深入探索C++對象模型》67頁最下面才會說第一版沒有拷貝構造函數,所以不能進行優化。其實是指優化的意義不大,或者說沒有什么可優化的。



但是這樣帶來的壞處是,如果你在拷貝構造函數里面放上與拷貝無關的代碼,比如我放入的printf和count++,那么這些東西就不會被調用了,產生優化前后代碼不一致問題。所以大家要在此注意一下。
http://www.linuxso.com/linuxbiancheng/5726.html

posted on 2012-03-28 17:30 大龍 閱讀(461) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            久久免费黄色| 欧美96在线丨欧| 国产欧美在线播放| 欧美在线999| 欧美在线视频观看| 一区在线观看| 欧美成人精品一区二区| 欧美成人免费视频| 日韩视频在线一区| 99国产精品99久久久久久| 欧美日韩精品免费观看| 亚洲在线一区| 久久av资源网| 亚洲人成免费| 夜夜嗨av一区二区三区四区| 欧美日韩综合视频网址| 久久国产精品久久w女人spa| 欧美中文在线字幕| 亚洲激情第一页| 99视频精品| 国产资源精品在线观看| 亚洲国产精品久久人人爱蜜臀 | 亚洲黄色高清| 欧美日韩精品综合| 久久精品国产亚洲a| 久久久综合网| 亚洲综合日韩在线| 老色鬼久久亚洲一区二区 | 国产麻豆视频精品| 久久精品在这里| 欧美精品免费在线| 久久福利一区| 欧美日产一区二区三区在线观看| 亚洲欧美国产va在线影院| 久久亚裔精品欧美| 性色av一区二区三区在线观看| 久久精品99国产精品| 在线视频一区观看| 久久久久国产精品午夜一区| 这里是久久伊人| 久久精品亚洲热| 亚洲在线观看| 欧美剧在线观看| 美女视频黄免费的久久| 国产乱码精品1区2区3区| 亚洲国产精品视频| 狠狠色丁香婷婷综合久久片| 亚洲欧洲日韩综合二区| 激情成人av在线| 亚洲男人的天堂在线| 99精品久久久| 蜜臀91精品一区二区三区| 欧美中文字幕在线| 欧美色大人视频| 亚洲黄色有码视频| 国产一区二区三区久久 | 国产精品视频免费一区| 欧美黄在线观看| 国产资源精品在线观看| 午夜精品久久久久久久男人的天堂 | 久久躁日日躁aaaaxxxx| 久久精品国产999大香线蕉| 欧美日韩一区二区三区在线观看免| 久久青青草综合| 国产日本亚洲高清| 亚洲女同在线| 性欧美8khd高清极品| 国产精品r级在线| 在线视频欧美一区| 亚洲一区影音先锋| 国产精品hd| 一区二区三区欧美视频| 亚洲女优在线| 国产精品婷婷| 亚洲伊人观看| 久久久免费观看视频| 狠狠综合久久| 麻豆国产精品777777在线| 欧美激情成人在线视频| 亚洲欧洲日韩在线| 欧美激情中文字幕一区二区| 亚洲国产日韩欧美在线图片 | 欧美日韩在线观看一区二区三区| 亚洲人体影院| 亚洲免费视频在线观看| 国产美女精品视频免费观看| 欧美一级视频| 欧美xx69| 99国内精品久久| 国产精品日韩精品欧美在线| 欧美亚洲一区二区在线| 久久婷婷人人澡人人喊人人爽| 伊人色综合久久天天五月婷| 嫩草成人www欧美| 99综合精品| 久久激情视频久久| 91久久夜色精品国产九色| 欧美视频网址| 久久久久久国产精品mv| 亚洲国产另类久久久精品极度| 一区二区三区国产精品| 国产欧美日韩精品一区| 久久综合狠狠综合久久激情| 日韩视频在线免费观看| 久久精品人人做人人爽电影蜜月| 亚洲国产精品毛片| 国产精品视频男人的天堂| 久久综合国产精品| 亚洲一区免费网站| 亚洲国产精品一区二区尤物区| 午夜天堂精品久久久久| 亚洲日本黄色| 国产视频一区免费看| 欧美精品v日韩精品v国产精品| 亚洲欧美日本日韩| 亚洲经典自拍| 老鸭窝91久久精品色噜噜导演| 一区二区三区国产精华| 精品电影一区| 国产精品福利av| 欧美高清视频在线| 欧美一区二区| 一区二区日韩精品| 欧美国产日韩一区二区三区| 欧美在线视频不卡| 一区二区三区欧美日韩| 在线精品视频在线观看高清| 欧美午夜激情在线| 欧美电影资源| 久久九九免费视频| 亚洲永久免费精品| 99国内精品久久| 亚洲大胆人体在线| 久久夜色精品国产亚洲aⅴ| 性娇小13――14欧美| 亚洲神马久久| 99成人在线| 亚洲精品综合精品自拍| 在线欧美一区| 亚洲福利视频二区| 亚洲福利在线观看| 亚洲国产1区| 91久久极品少妇xxxxⅹ软件| 亚洲国产精品悠悠久久琪琪| 黄色精品一区| 在线视频国内自拍亚洲视频| 国产一区二区三区最好精华液| 国产精品一区二区久久| 国产免费观看久久黄| 国产精品色午夜在线观看| 国产精品美女www爽爽爽视频| 国产精品草莓在线免费观看| 欧美午夜视频一区二区| 国产精品久久网| 国产精品视频一| 国产主播精品| 亚洲盗摄视频| 亚洲精品免费看| 99视频一区| 亚洲伊人伊色伊影伊综合网| 欧美一区二区黄| 久久久久久综合网天天| 老司机精品导航| 欧美韩日一区二区| 亚洲激情影视| 亚洲一区精品电影| 久久久精品999| 欧美大片在线看免费观看| 欧美午夜精品理论片a级按摩| 国产精品视频午夜| 在线成人av.com| 日韩视频在线永久播放| 午夜久久久久久| 玖玖在线精品| 99国产精品99久久久久久| 午夜视频一区| 免费成人高清在线视频| 欧美日韩一二三四五区| 国产精品亚洲综合| 亚洲国产cao| 一区二区不卡在线视频 午夜欧美不卡在| 在线综合亚洲| 久久久免费精品| 亚洲欧洲另类国产综合| 午夜在线观看欧美| 欧美va亚洲va日韩∨a综合色| 国产精品黄色在线观看| 国内外成人在线视频| 一本大道久久a久久精二百| 久久精品一区二区三区四区| 91久久视频| 午夜精品一区二区三区在线| 欧美成人免费网站| 国产一区二区三区四区五区美女 | 国产一区二区三区高清| 日韩特黄影片| 久久久久看片| 亚洲一区二区高清| 欧美理论电影网| 激情五月***国产精品|