Jac*_*ack 5 c++ constructor copy-constructor move-constructor c++11
为什么在从而bar不是移动构造函数返回时调用复制构造函数?
#include <iostream>
using namespace std;
class Alpha {
public:
Alpha() { cout << "ctor" << endl; }
Alpha(Alpha &) { cout << "copy ctor" << endl; }
Alpha(Alpha &&) { cout << "move ctor" << endl; }
Alpha &operator=(Alpha &) { cout << "copy asgn op" << endl; }
Alpha &operator=(Alpha &&) { cout << "move asgn op" << endl; }
};
Alpha foo(Alpha a) {
return a; // Move ctor is called (expected).
}
Alpha bar(Alpha &&a) {
return a; // Copy ctor is called (unexpected).
}
int main() {
Alpha a, b;
a = foo(a);
a = foo(Alpha());
a = bar(Alpha());
b = a;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果bar是,return move(a)则行为符合预期.我不明白为什么调用std::move是必要的,因为foo在返回时调用move构造函数.
在这种情况下,有两件事需要理解:
ainbar(Alpha &&a)是一个命名的右值引用;因此,被视为左值。a还是有参考意义的。第1部分
由于ainbar(Alpha &&a)是命名右值引用,因此将其视为左值。将命名右值引用视为左值的动机是为了提供安全性。考虑以下,
Alpha bar(Alpha &&a) {
baz(a);
qux(a);
return a;
}
Run Code Online (Sandbox Code Playgroud)
如果baz(a)被视为a右值,则可以自由调用移动构造函数,并且qux(a)可能无效。该标准通过将命名右值引用视为左值来避免此问题。
第2部分
由于a仍然是一个引用(并且可能引用 范围之外的对象bar),bar因此在返回时调用复制构造函数。这种行为背后的动机是为了提供安全。
参考
| 归档时间: |
|
| 查看次数: |
180 次 |
| 最近记录: |