20 協助完成「返回值優化(RVO)」

2021-06-05 22:07:24 字數 2156 閱讀 2614

[19]最後曾提到了在函式通過傳值方式(by value)返回乙個物件時,不可避免地要生成乙個臨時物件,這會嚴重影響到程式的效率,如下例計算兩個分式的乘積:

class

crational

int numer() const

//get numerator

int denom() const

//get denominator

private

:

intnumerator;

intdenominator;

};const crational operator *(const crational& lhs, const crational&rhs)

crational a(

1, 3

);crational b(

2, 3

);crational c = a * b; //

呼叫函式 operator *()

我們來仔細分析一下operator * 完成的功能,生成乙個區域性物件res ,呼叫建構函式進行了初始化,函式返回時,還會生成乙個臨時變數,用res進行copy constructor,返回之後會銷毀res物件,而呼叫c = a * b; 時將臨時物件用來初始化c,然後再銷毀這個臨時變數。

上面這一系列的構造、析構物件,嚴重影響了程式的效能,那麼有什麼辦法可以消除這種影響呢?

能否通過返回乙個物件指標呢?將例項的函式改為:

const crational* operator *(const crational& lhs, const crational&rhs)

crational c = * (a * b); //

呼叫函式

暫不說最後呼叫函式的表示式看起來很不自然,最嚴重的問題是這樣寫容易導致記憶體洩漏,因為我們往往會忘記釋放函式返回來的指標。

能否通過返回物件的reference呢?於是上面的例項的函式被修改為:

const crational& operator *(const crational& lhs, const crational&rhs)

crational c = a * b; //

看起來沒啥問題對吧?

貌似這種做法,可以不用生成臨時物件,因為返回的是物件的引用,直接指向res。事實上,這種做法是錯誤的!函式返回的是reference,指向乙個區域性物件,而區域性物件在函式返回時是要被釋放的,因此res在operator *返回時已經不存在了,所以這種做法是不被編譯器允許的!

額...貌似沒什麼其他辦法消除返回的臨時物件了,那麼能否通過其他方式讓編譯器消除生成臨時物件的成本呢?

我們的做法是:返回constructor arguments 取代區域性物件!如下:

const crational operator *(const crational& lhs, const crational&rhs)

看起來和最開始的做法沒什麼區別吧....因為還是要生成函式內部臨時物件已經函式返回臨時物件!但是,這種做法下c++允許編譯器將臨時物件進行優化,使它們不存在。如呼叫

crational c = a * b;

臨時物件構造與c的記憶體內,這樣整個過程,你只需付出乙個constructor(用來生成c)的代價,而並沒有函式內部和返回時臨時物件的構造和析構的代價了。

如果將函式再定義為內聯函式,將又會節省函式呼叫的成本。下面是乙個最有效的做法:

inline const crational operator *(const crational& lhs, const crational&rhs)

crational c = a *b;

//與下面的語句幾乎具有相同的代價

crational c(a.numer() * b.numer(), a.denom() * b.denom());

而編譯器這種優化行為,被稱為"returnvalueoptimization"(rvo)!

效率 條款20 協助完成「返回值優化(RVO)」

函式如果返回物件,對效率狂而言是乙個嚴重的挫折,因為以by value方式返回物件,背後隱藏的constructor和destructor都將無法消除。有的人會返回指標,於是導致下列這種拙劣的語法形式 const rational operator const rational lhs,const ...

協助完成返回值的優化

乙個返回物件的函式很難有較高的效率,因為傳值返回會導致呼叫物件內的構造和析構函式,這種呼叫是不能避免的。問題很簡單 乙個函式要麼為了保證正確的行為而返回物件要麼就不這麼做。如果它返回了物件,就沒有辦法擺脫被返回的物件。就說到這。考慮rational 有理數 類的成員函式operator class ...

C 返回值優化RVO

返回值優化,是一種屬於編譯器的技術,它通過轉換源 和物件的建立來加快源 的執行速度。rvo return value optimization。測試平台 stm32f103vg keil 5.15 背景 我們有個macaddress toarray byte macaddress toarray c...