A类定义所有复制/移动构造函数/赋值,如下所示:
struct A
{
std::string s;
A() : s("test") { }
A(const A& other) : s(other.s) { std::cout << "Copy constructor\n";}
A(A&& other) : s(std::move(other.s)) { std::cout << "Move constructor\n";}
A& operator= (const A& other) { std::cout << "Copy assignment\n"; s = other.s; return *this;}
A& operator= (A&& other) { std::cout << "Move assignment\n"; s = std::move(other.s); return *this;}
};
以下是返回A类对象的函数:
A f(A a) { return a; }
A g() { return A(); }
main()
功能是:
int main()
{
A a1 = f(A()); // Move-construct
A a2 = std::move(a1); // Move-construct
A a3 (std::move(a2)); // Move-construct
A a4 (a1); // Copy-construct
A a5 = a4; // Copy-construct
a5 = f(A()); // Move constructor + Move assignment
a5 = a4; // Copy assignment
a5 = g(); // Move assignment
A a6 = g(); // None!! Member-wise assignment (?)
}
任何人都可以告诉我,为什么在a6
没有调用构造函数和赋值运算符? C ++ 11的哪些文档描述了这种行为?
答案 0 :(得分:3)
这称为复制省略,在 C ++标准,第12.8节第31页中有描述。
当满足某些条件时,允许省略实现 复制/移动类对象的构造,即使构造函数 选择用于复制/移动操作和/或析构函数 对象有副作用。在这种情况下,实施处理 省略的复制/移动操作的源和目标只是两个 引用同一个对象的不同方式(...)
也描述了这种情况。其中之一是:
当一个临时类对象尚未绑定到引用时 将被复制/移动到具有相同cv-unqualified的类对象 类型,通过构造,可以省略复制/移动操作 临时对象直接进入省略的复制/移动目标
当g()返回一个临时匿名对象(未绑定到引用)时,is直接构造到目标a6中。在您的示例中,使用了g&#39的return语句的默认构造函数。
答案 1 :(得分:1)
A a6 = g();
中的http://en.wikipedia.org/wiki/Return_value_optimization,g
中的代码通过调用a6
内部A
构造函数创建g
{ {1}}。