有人可以解释这个 c++ 程序的输出吗?
Can someone explain the output of this c++ program?
为什么输出foo3
等于3
? 我建议,当调用bar(foo1)
时,函数bar
在堆栈上创建foo1
的副本,因此它的值等于 0,当返回此值时,foo3
的复制构造函数再次递增该值,所以它应该是 2?
提前谢谢。
这是我的代码:
#include <iostream>
struct Foo {
Foo()
: x(0)
{
}
Foo(const Foo& foo)
: x(foo.x + 1)
{
}
int x;
};
Foo bar(Foo foo)
{
foo.x++;
return foo;
}
int main()
{
Foo foo1;
Foo foo2 = foo1;
std::cout << "A:" << foo1.x << std::endl;
std::cout << "B:" << foo2.x << std::endl;
Foo foo3 = bar(foo1);
std::cout << "C:" << foo3.x << std::endl;
}
输出:
A:0
B:1
C:3
我相信这里有三个复制构造函数在工作,行foo2 = foo1
,将foo1
传递到bar
,以及从bar
返回foo1
。
修改代码可以清楚地了解正在发生的事情:
#include <iostream>
struct Foo {
Foo()
: x(0)
{
std::cout << "Constructor called" << std::endl;
}
Foo(const Foo& foo)
: x(foo.x + 1)
{
std::cout << "Copy constructor called" << std::endl;
}
int x;
};
Foo bar(Foo foo)
{
std::cout << "B2:" << foo.x << std::endl;
foo.x++;
return foo;
}
int main()
{
Foo foo1;
Foo foo2 = foo1;
std::cout << "A:" << foo1.x << std::endl;
std::cout << "B:" << foo2.x << std::endl;
Foo foo3 = bar(foo1);
std::cout << "C:" << foo3.x << std::endl;
}
输出:
Constructor called
Copy constructor called
A:0
B:1
Copy constructor called
B2:1
Copy constructor called
C:3
0 -> 1
您将foo1
复制到bar
的参数。1 -> 2
在bar
内递增x
。2 -> 3
将bar
复制到临时返回值。
我数了三个增量。
执行时:
Foo foo2 = foo1;
您正在调用复制 CTR,因此 foo2.x 的值将为 1。 然后在调用时:
Foo foo3 = bar(foo1);
因为您不是通过引用传递的,所以 'bar' 的参数是使用复制 ctor (x == 1) 将 foo1 的副本创建到柱线中。之后,该副本的 x 成员递增 (x == 2) 并最终返回。当返回时不创建另一个副本,因为"返回值优化"(仍然 x == 2)。 最后,foo3 再次使用复制 ctor(x == 3) 进行初始化。
当你创建第一个foo1
时,它的x
为零。对bar
的调用按值传递,因此它被复制 - 因此bar
中的参数的值为 1。函数本身bar
进一步递增x
1,因此现在是 2。最后,return 语句再次按值返回,因此还有另一个副本 - 因此最终x
为 3。
注意 RVO 在这里不适用,因为Foo
不是按值返回局部变量 - 而是返回一个参数,该参数实际上必须复制。
从标准 [class.copy/31] 中,允许复制省略的情况,其中明确排除了返回函数参数的情况:
— 在具有类返回类型的函数中的 return 语句中,当 表达式是非易失性自动对象的名称(其他 比函数或 catch 子句参数)具有相同的 cv 不合格 类型作为函数返回类型,复制/移动操作可以是 通过将自动对象直接构造到 函数的返回值
- 如何从Windows应用程序输出到标准?
- 在由Sublime文本3编译后在cmd上显示Java程序输出
- 如何从 Win32 C++ 应用程序输出到父控制台窗口?
- 而循环:简单的除法程序输出零,不明白为什么
- Qt creator 4.11,在应用程序输出面板中创建一个链接
- 使用复制构造函数的程序输出错误
- 为什么Qt Creator的应用程序输出不能从spdlog记录器打印
- 为什么在 Direct X 11 中没有我的程序输出?
- 我怎样才能阻止我的程序输出时间,它使我的程序难以阅读
- 程序输出奇怪的字符
- 程序输出"nan"
- 为什么我的C++程序输出不同的数字来将米转换为英尺?
- 3D 纹理大小会影响程序输出,而不会引发错误
- C++,程序输出无效输入,但继续通过循环
- 如何连接C++和Excel(从C++程序输出到Excel电子表格)
- 为什么我的C 程序输出乱码代码
- QT小部件应用程序输出到控制台
- 混淆了具有虚拟继承的程序输出
- 为什么我的C++程序输出这个
- 为什么我的程序输出不断变化?EAX寄存器不断更改值