簡體   English   中英

在此C ++代碼段中,復制構造函數被調用多少次?

[英]How many times is the copy constructor is called in this C++ snippet?

在這個問題中,我們必須找出一個復制構造函數被調用了多少次,根據我的說法,它的5次回答為7。那是怎么回事?

Widget  f(Widget  u)
{
    Widget v(u);
    Widget w = v;
    return w;
}
int main()
{
    Widget x;
    Widget y = f(f(x));
}

在禁用復制刪除和移動的情況下,有:

1) Widget y = f(f(x));

f函數中有4個調用來復制構造函數。

1) u通過值傳遞。

2) v是從u復制初始化的。

3) w是從v復制初始化的。

4) w在返回時被復制。

因此,實際上有9個電話。

啟用復制刪除功能后,gcc / clang上有5個調用。

根據我的說法,復制構造函數被調用了幾次,但答案是7。這是怎么回事?

將代碼段更新為實際有效的代碼(請參閱底部)后,您可以看到以下輸出( test.cpp代碼):

➜  /tmp g++ -o test -std=c++11 test.cpp && ./test
default ctor
copy ctor
copy ctor
copy ctor
copy ctor
copy ctor

我們只需要查看單個函數調用的工作方式即可。 為此,我們有:

Widget  f(Widget  u)
{
        Widget v(u);
        Widget w = v;
        return w;
}

y = f(x)

復制ctor在以下情況下被調用:

  • 通過值將x發送到f
  • f u創建v
  • f中將v分配給w
  • f返回w
  • f的返回值分配給y

因此,對於f每個調用,我們需要使用復制ctor 4次,並且由於f被調用兩次,因此您已經有+8復制ctor調用,因此y的最終賦值+1 ,總計9

但是為什么我們在上面的輸出中只看到5?

答案是:優化

GCC正在通過優化刪除一些復制操作。 如果使用-fno-elide-constructors標志構建它,那么我們可以看到所有它們:

➜  /tmp  g++ -fno-elide-constructors -o -std=c++11 test test.cpp && ./test
def ctor
copy ctor
copy ctor
copy ctor
copy ctor
copy ctor
copy ctor
copy ctor
copy ctor
copy ctor

這告訴GCC 不要執行先前構建中看到的優化,該優化顯示了所有用於x的默認構造函數下面的復制構造函數調用。

使用的代碼段

#include <iostream>
using namespace std;

class Widget {

public:
        Widget() { cout << "def ctor" << endl; }
        Widget(const Widget &other) { cout << "copy ctor" << endl; }
};

Widget  f(Widget u)
{
        Widget v(u);
        Widget w = v;
        return w;
}

int main()
{
        Widget x;
        Widget y = f(f(x));
        return 0;
}

+1-分配Widget y = f(f(x))

+2-調用函數f()兩次,按值而不是引用傳遞參數。

+2-復制v(u)兩次

+2-復制初始化Widget w = v調用了兩次

使7。

請注意,對於某些設置下的某些編譯器而言,這是正確的。 其他答案也是正確的,我解釋了為什么結果可以為7的原因,例如,您可以在bcc32下獲得該結果。

暫無
暫無

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

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