在初始化具有函数的返回值的对象时,不会调用复制构造函数 [英] Copy constructor not called when initializing an object with return value of a function
问题描述
请考虑以下代码:
#include <iostream>
using namespace std;
class A
{
public:
int a;
A(): a(5)
{
cout << "Constructor\n";
}
A(const A &b)
{
a = b.a;
cout << "Copy Constructor\n";
}
A fun(A a)
{
return a;
}
};
int main()
{
A a, c;
A b = a.fun(c);
return 0;
}
上述代码与 g ++文件的输出。 cpp
是:
Constructor
Constructor
Copy Constructor
Copy Constructor
上述代码的输出为 g ++ -fno-elide-构造函数file.cpp
是:
Constructor
Constructor
Copy Constructor
Copy Constructor
Copy Constructor
我知道返回值优化。我的问题是调用拷贝构造函数(返回过程中的临时对象或返回的对象被复制到B)被省略?
I know Return Value Optimization. My question is which call to copy constructor is elided(temporary object during returning or returned object being copied to b)?
如果消隐拷贝构造函数用于创建一个b,则是如何b。在所有已创建的(因为在这种情况下,也没有构造函数调用)?
If the elided copy constructor is the one used for creating b, then how is b created at all (because there is no constructor call in this case also)?
如果我更换行 A b = a.fun(C);
与 a.fun(C)
和编译使用第一种方法,甚至第二种方法,那么也拷贝构造函数被调用了2次。所以,如果在案件上段所述,临时对象的拷贝构造函数会被省略,那么为什么是不是在这种情况下省略?
If I replace the line A b = a.fun(c);
with a.fun(c)
and compile using the first method or even the second method, then also the copy constructor is being called 2 times . So, if in the case explained in the previous paragraph, the temporary object's copy constructor is elided, then why isn't it elided in this case?
推荐答案
#include <iostream>
using namespace std;
class A
{
public:
int a;
A(): a(5)
{
cout << "Constructing: " << (void *)this << std::endl;
}
A(const A &b)
{
a = b.a;
cout << "Copy Constructor: " << (void *)this << " from " << (void *)&b << std::endl;
}
A fun(A a)
{
return a;
}
};
int main()
{
A a, c;
A b = a.fun(c);
std::cout << "a:" << (void *)&a << std::endl <<
"b:" << (void *)&b << std::endl <<
"c:" << (void *)&c << std::endl;
return 0;
}
产量:
Constructing: 0x7fffbb377220
Constructing: 0x7fffbb377210
Copy Constructor: 0x7fffbb377230 from 0x7fffbb377210
Copy Constructor: 0x7fffbb377200 from 0x7fffbb377230
a:0x7fffbb377220
b:0x7fffbb377200
c:0x7fffbb377210
因此,它构造 a
,构造 c
,将 c
复制到中间(参数 code>的功能),然后直接复制中间插入
b
,跳过一个典型的复制到中间回报。如果你传递值(更改为 A fun(const A& a)
:
So it constructs a
, constructs c
, copies c
to an intermediate (argument a
of the function), and then copies the intermediate directly into b
, skipping the typical copying of a to a return intermediate. This is even better demonstrated if you pass by value (change to A fun(const A& a)
:
Constructing: 0x7fff8e9642b0
Constructing: 0x7fff8e9642a0
Copy Constructor: 0x7fff8e964290 from 0x7fff8e9642a0
a:0x7fff8e9642b0
b:0x7fff8e964290
c:0x7fff8e9642a0
一个构造,C构造,C是直接复制到b,尽管b没有被传递到乐趣!
a is constructed, c is constructed, c is copied directly to b, despite b not being passed to fun!
这篇关于在初始化具有函数的返回值的对象时,不会调用复制构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!