返回值優化(Return Value Optimization -- RVO)

返回值優化(Return Value Optimization – RVO)

在日常開發中,我們不得不會遇到返回對象的情況。那麼對於 追求效率 的程序員來說,返回對象是一件很痛苦的事情。

舉個栗子🌰

考慮這樣的一種情況:分數相乘

有這麼一個分數類:

#include <iostream>

class Rational {
public:    
    Rational (int numerator = 0, int denominator = 1);
	...
    int numerator() const;
    int denominator() const;
};

那麼 operator*應該是這樣的

const Rational operator*(const Rational& lhs, const Rational& rhs);

這個情況下,就算我們看不到函數內容,我們都知道應該是返回對象的。因爲是兩個任意的數相乘,沒有辦法在不構造新對象的情況下返回結果。

錯誤一:返回指針

有些人可能會想到在函數內部動態開闢一段空間,在這個空間上構造一次對象,然後返回指針就可以了,這樣就可以避免在返回的時候又要構造臨時對象的開銷。

但是,如果動態開闢空間,那麼在 C/C++ 中是要手動釋放的,如果程序員忘記釋放內存,就會造成內存泄漏的問題。所以這個方法是不可取的。

錯誤二:返回引用

如果說返回指針是一個不妥的行爲,那麼返回引用就是一個滑稽的行爲。

因爲如果你返回在函數內部構造的對象的引用。那麼當這個函數結束後,編譯器會自動銷燬對象,那麼用戶拿到的就只是一個被銷燬的對象,產生的行爲就是未定義行爲。

那麼應該怎麼樣去設計這個函數在保證安全的情況下又能讓效率最大?

const Rational operator*(const Rational& lhs, const Rational& rhs) {
    return Rational(lhs.numerator() * rhs.numerator(), lhs.denominator * rhs.denominator())
}

這樣看上去僅僅是構造了一個臨時對象然後返回。難道不是還需要編譯器銷燬該對象,再構造匿名臨時對象返回嗎?

但是 C++ 允許編譯器將臨時對象優化,使它們不存在。你的編譯器可以將 return 表達式所定義的對象構造於 C 的內存中。那麼這樣你就只需要一次構造就可以啦。

這種方法叫做 Return Value Optimization 簡稱 RVO。

叮~🔔

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章