初識c (31)之返回值優化

2021-09-26 10:56:39 字數 1568 閱讀 8386

返回值優化(return value optimization,縮寫為rvo)是c++的一項編譯優化技術。它最大的好處是在於: 可以省略函式返回過程中複製建構函式的多餘呼叫,解決 「c++ 中長久以來為人們所詬病的臨時物件的效率問題」。

先來看一下測試**:

#includeusing namespace std; 

class a

a(const a& a):m_ptr(new int(*a.m_ptr))

~a()

private:

int* m_ptr;

};a geta()

int main()

我們的編譯器大多數都是預設返回值優化的。

返回值優化的執行結果:

建構函式

析構函式

如果在編譯時設定編譯選項  -fno-elide-constructors 編譯器就會不進行返回值優化,結果如下:

建構函式

深拷貝建構函式

析構函式

深拷貝建構函式

析構函式

析構函式

有沒有震驚到你,原來編譯器這麼給力。我們來捋一下整個過程;

首先函式gata()中,a a;這句話會呼叫第乙個建構函式。

然後函式gata()中,return a;由於返回值是值傳遞,a需要拷貝給gata()的返回值,呼叫一次拷貝建構函式。

退出函式gata()時,a需要被解析掉,呼叫一次析構函式。

然後回到主函式中,gata()返回的是乙個臨時變數,將這個臨時變數賦給主函式中的a,呼叫一次構造拷貝函式

臨時變數在所在語句執行結束後,死亡,呼叫一次析構函式。

退出主函式之前,主函式中的a,需要解析掉,呼叫一次析構函式。

對比兩次的輸出結果很顯然。非rvo時,多做了兩次拷貝建構函式,分別是第二步和第四步。如果我們的類是乙個容量比較大的類的話,建構函式的代價是很大的,rvo很大程度上提高了c++的效率。

下面是rvo只優化第四步的一種情況:

#includeusing namespace std; 

class a

a(const a& a):m_ptr(new int(*a.m_ptr))

~a()

private:

int* m_ptr;};

a geta(int i)

else}

int main()

非優化結果:

建構函式

深拷貝建構函式

析構函式

深拷貝建構函式

析構函式

析構函式

優化結果:

建構函式

深拷貝建構函式

析構函式

析構函式

在網上看到很多人說這是rvo失效的情況,其實不然,只是優化了一半。

為了解決這種問題c++11也重新定義了右值,雖然並沒有編譯器做出的優化好,但是從語法來解決這個問題,不依賴於編譯器,適應性強。所以我們還是要學習右值的定義。請參考我的另一篇部落格:

C 返回值優化

當函式需要返回物件時,通常有兩種寫法,一種是直接在return語句中返回乙個物件,一種是先構造好乙個物件,然後在return中將其返回。以下 為例 include include using namespace std struct node node const node n name n.nam...

返回值優化

通過傳值方式返回要建立新物件時,應注意使用的形式,例如在operator return integer left.l right.l 咋看起來這像是乙個 對乙個建構函式的呼叫 其實並非如此。這是臨時物件語法,它是在說 建立乙個臨時integer物件並返回它 據此我們可能認為如果建立乙個有名字的區域性...

返回值優化

返回值優化,是一種屬於編譯器的技術,它通過轉換源 和物件的建立來加快源 的執行速度。rvo return value optimization。class complex 複數 complex const complex a real a.real imag a.imag complex opera...