簡體   English   中英

c ++中的臨時對象如何影響效率?

[英]How the temporary objects in c++ affect the efficiency?

我讀過一篇關於CodeProject的文章http://www.codeproject.com/Tips/103648/C-Tip-How-to-eliminate-Temporary-Objects

Complex y,z;
Complex x=y+z; /* initialization instead of assignment */

我混淆了為什么第二個語句沒有創建臨時對象? 編譯器如何工作?

C ++中有一條規則,如果它們直接用於初始化,它允許編譯器同步臨時數據。
無論如何,使用它的余地,編譯器可以在沒有這個規則的情況下優化示例,這具有相同的效果。

12.8復制和移動類對象§32

當滿足某些條件時,允許實現省略類對象的復制/移動構造,即使該對象的復制/移動構造函數和/或析構函數具有副作用。 在這種情況下,實現將省略的復制/移動操作的源和目標視為僅僅兩種不同的引用同一對象的方式,並且該對象的銷毀發生在兩個對象的后期時間。在沒有優化的情況下銷毀.123在下列情況下允許復制/移動操作(稱為復制省略)的這種省略(可以合並以消除多個副本):
- 在具有類返回類型的函數的return語句中,當表達式是具有與函數返回類型相同的cvunqualified類型的非易失性自動對象(函數或catch子句參數除外)的名稱時,通過將自動對象直接構造到函數的返回值中,可以省略復制/移動操作
- 在throw-expression中,當操作數是非易失性自動對象的名稱(函數或catch子句參數除外),其范圍不會超出最內層封閉try-block的末尾(如果有的話)一),通過將自動對象直接構造到異常對象中,可以省略從操作數到異常對象(15.1)的復制/移動操作
- 當一個未綁定到引用(12.2)的臨時類對象被復制/移動到具有相同cv-nonqualified類型的類對象時,可以通過將臨時對象直接構造到該對象中來省略復制/移動操作。省略的復制/移動的目標
- 當異常處理程序的異常聲明(第15條)聲明一個相同類型的對象(cv-qualification除外)作為異常對象(15.1)時,可以通過處理異常聲明來省略復制/移動操作如果除了為exception-declaration聲明的對象執行構造函數和析構函數之外,程序的含義將保持不變,則作為異常對象的別名。

在您提供的鏈接的第一個示例中,調用賦值運算符:

Complex x, y, z;
x=y+z;

在您提供的鏈接的第二個示例中,將調用構造函數:

Complex y,z;
Complex x=y+z;

但在這兩種情況下,都會創建一個臨時對象(包含x+y的值)。

所以我嚴重懷疑這個鏈接的正確性。

我很樂意閱讀你的問題的任何答案,否則解釋......


我們可以避免的臨時對象通常是傳遞給函數或通過值而不是通過引用從函數返回的對象。

例如,在下面的Complex::operator+=中,在調用函數時在堆棧上創建一個臨時對象,並在函數返回時在堆棧上創建另一個臨時對象:

Complex Complex::operator+=(Complex num)
{
    this->real += num.real;
    this->imag += num.imag;
    return *this;
}

void func()
{
    Complex a(1,2);
    Complex b(3,4);
    a += b;
    ...
}

為了消除這兩個臨時對象,您可以簡單地通過引用傳遞和返回:

Complex& Complex::operator+=(Complex& num)
{
    ...
}

請注意, 通過引用傳遞參數在成員函數和全局函數中是可行的,但是通過引用返回參數僅在成員函數中是可行的(除非您從全局函數返回全局變量,但這在在大多數情況下)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM