[英]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
。
答案是:優化
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.