cri*_*ron 9 c++ copy-constructor temporary-objects return-value-optimization copy-elision
请考虑以下代码:
#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;
}
Run Code Online (Sandbox Code Playgroud)
上面代码的输出g++ file.cpp是:
Constructor
Constructor
Copy Constructor
Copy Constructor
Run Code Online (Sandbox Code Playgroud)
上面代码的输出g++ -fno-elide-constructors file.cpp是:
Constructor
Constructor
Copy Constructor
Copy Constructor
Copy Constructor
Run Code Online (Sandbox Code Playgroud)
我知道返回值优化.我的问题是哪个复制构造函数的调用被删除(返回期间的临时对象或被复制到b的返回对象)?
如果省略的复制构造函数是用于创建b的构造函数,那么如何创建b(因为在这种情况下也没有构造函数调用)?
如果我替换行A b = a.fun(c);与a.fun(c)和使用第一种方法或者甚至第二方法进行编译,则还复制构造是被称为2次.因此,如果在上一段中解释的情况下,临时对象的复制构造函数被省略了,那么为什么在这种情况下它没有被省略呢?
#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;
}
Run Code Online (Sandbox Code Playgroud)
产量:
Constructing: 0x7fffbb377220
Constructing: 0x7fffbb377210
Copy Constructor: 0x7fffbb377230 from 0x7fffbb377210
Copy Constructor: 0x7fffbb377200 from 0x7fffbb377230
a:0x7fffbb377220
b:0x7fffbb377200
c:0x7fffbb377210
Run Code Online (Sandbox Code Playgroud)
因此它构造a,构造c,复制c到中间体(函数的参数a),然后将中间体直接b复制到,跳过典型的a复制到返回中间体.如果您通过值传递,则更好地证明了这一点(更改为A fun(const A& a):
Constructing: 0x7fff8e9642b0
Constructing: 0x7fff8e9642a0
Copy Constructor: 0x7fff8e964290 from 0x7fff8e9642a0
a:0x7fff8e9642b0
b:0x7fff8e964290
c:0x7fff8e9642a0
Run Code Online (Sandbox Code Playgroud)
a构造,c构造,c直接复制到b,尽管b没有传递给乐趣!
| 归档时间: |
|
| 查看次数: |
605 次 |
| 最近记录: |