簡體   English   中英

當按值傳遞右值到函數時,為什么不調用復制構造函數

[英]Why isn't the copy-constructor called when passing rvalue by value to function

我以某種方式錯過了這件事,但我感到驚訝。 考慮以下代碼示例:

#include <iostream>

class A
{
    int a;

public:
    A(int a) : a(a) { std::cout << "Normal constructor called." << std::endl; }
    A(const A& orig) : a(orig.a) { std::cout << "Copy constructor called." << std::endl; }
};

void testFunction1(const A arg) { std::cout << "testFunction1()" << std::endl; }
void testFunction2(const A& arg) { std::cout << "testFunction2()" << std::endl; }

int main()
{
   testFunction1(A(2));

   testFunction2(A(2));

   return 0;
}

我期望得到以下結果:

/* Normal constructor called. */
/* Copy constructor called. */
/* testFunction1() */
/* Normal constructor called. */
/* testFunction2() */

但是我錯了。 確切的結果如下:

/* Normal constructor called. */
/* testFunction1() */
/* Normal constructor called. */
/* testFunction2() */

當我按值將A(2)傳遞給testFunction1()時,為什么不調用復制構造函數? 這是否意味着在C ++ 98中按值或引用傳遞右值之間沒有區別? 是優化嗎? A(2)argtestFunction1()是否完全是同一對象?

是優化嗎?

是! 這稱為Copy Elision ,如果可能的話,可以根據編譯器刪除(繞過)副本。

因此,在您的情況下,編譯器知道無需調用復制構造函數即可擺脫該錯誤,並做到了這一點。 請注意,即使您使用arg ,例如調用A的打印成員函數,出於優化目的,編譯器仍然可以使用復制省略。 換句話說,不使用arg並不是此行為的原因。

如果您使用古老的編譯器,或者調整當前編譯器的設置,則可能會在一開始就看到期望的結果。

如Guillaume Racicot所述,使用可以確保在這種情況下進行復制省略。

暫無
暫無

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

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