C 中的RVO與NVR優化

2021-07-02 06:02:36 字數 2054 閱讀 2599

語義上,函式呼叫結束,返回值會通過拷貝構造乙個臨時匿名物件傳出來(因為函式體中的都是區域性變數,return後的物件呼叫完成都超過作用域,不存在了)。

先上**:

#include using namespace std;

class myclass

//預設建構函式

myclass(const myclass& that); //拷貝建構函式

myclass& operator=(const myclass& that); //賦值建構函式

};myclass::myclass(const myclass& that)

myclass& myclass::operator=(const myclass& that)

else }

myclass gfunc()

myclass func()

int main()

在vs2013下,最終的輸出結果如下:

myobj = gfunc()這句,一共有3次建構函式的呼叫。包括gfunc()函式體內部的區域性物件obj的構造,return返回值乙個匿名的臨時物件的構造。gfunc()函式體執行完成,return之後的obj物件已經消亡,為了把返回值傳出來,必須借助於這個臨時物件。

借助於c++編譯器的rvo技術(return value optimization),返回值優化,return 後是呼叫建構函式:若是用來給物件賦值,則會省掉一次拷貝建構函式的呼叫(用來傳出返回值的匿名臨時物件),**中的 myobj3 = func();若是用來初始化物件,那麼還可以省掉一次賦值建構函式的呼叫,**中的  myclass myobj3 = func()。(注意這裡要區別c++中的初始化和賦值,初始化是分配空間的同時賦值,乙個語句完成;而賦值是先前已經有了空間)。

如果return 之後,是乙個具名的物件,編譯器可以做 nrv 優化(named return value optimization),具名返回值優化。此時如果返回值用來初始化物件,可以省掉一次賦值建構函式的呼叫。 **中的  myclass myobj2 = gfunc() ,相當於直接用把return 後的臨時物件拷貝構造到myobj2中。

上邊兩條是編譯器預設就提供的,比如在vs下。

如果編譯器的優化能力更強,還存在更強的nvr優化技術,能省掉拷貝建構函式的呼叫。

在gfunc()函式中,內部通過預設建構函式區域性變數obj,最後又return這個區域性變數obj,對於myclass myobj2 = gfunc() 語句,完全可以直接將myobj2 代替obj,可以在前邊的基礎上省掉了拷貝建構函式的呼叫。myobj = gfunc() 則可以直接將return 後的結果賦值給myobj ,也省掉了拷貝建構函式的呼叫。

上邊的**在gcc -o優化編譯下,輸出為:

可以看到如果return 後是乙個具名變數,也就是是個左值;nrv優化可以省去拷貝構造乙個臨時匿名變數。gcc下比較好開啟,vs中暫時沒找到啟用方法。

由於nrv優化的存在,可以return之後直接返回乙個具名的物件。萬一不支援nrv技術,將會拷貝構造乙個匿名的臨時物件,而且如果存在移動拷貝建構函式,預設的總是移動拷貝建構函式的效率更好,所以當存在移動拷貝建構函式時,將是移動拷貝構造乙個臨時匿名物件,雖然此時return 後的是乙個具名的左值 result,實際相當於 return move(result).

看這裡的栗子

上邊這個栗子中,函式的返回值型別不能是指向臨時變數的引用(無論左值引用還是右值引用)和指標的原則是不能變的;不過可以將函式的返回值(本身可以是個臨時變數),賦值給右值引用或者const 左值引用。注意前後的差別。因為函式呼叫結束,返回值變不存在,實際呼叫結束返回值是return 後的值的乙個拷貝,return 後的那個在呼叫結束一定是不存在的。

右值引用和const左值引用,會延長臨時變數的生存週期,使得引用變數存在時,臨時變數也是存在的。

C 中的RVO與NVR優化

rvo技術 return value optimization,匿名返回值優化 nrvo技術 named return value optimization,具名返回值優化 關鍵 1 語義上,函式呼叫結束,返回值會通過拷貝構造乙個臨時匿名物件傳出來 因為函式體中的都是區域性變數,return後的物件...

C 中 NRVO優化與RVO優化

rvo return value optimization 和nrvo named return value optimization 是c 在處理 返回乙個class object的函式 時常用的優化技術,主要作用就是消除臨時物件的構造和析構成本。目前我正在研究 深度探索c 物件模型 對於這兩種常...

C 中的RVO優化和NRVO優化

rvo return value optimization 和nrvo named return value optimization 是c 在處理乙個函式返回類物件並將返回值賦給另乙個物件時,為了減少拷貝構造次數以及析構次數而採用的一種編譯器優化技術。本篇部落格以 深度探索c 物件模型 中例子來總...