Fla*_*ame 5 c++ rvalue-reference assignment-operator copy-and-swap c++11
如果我有一个类如
class Foo{
public:
Foo(){...}
Foo(Foo && rhs){...}
operator=(Foo rhs){ swap(*this, rhs);}
void swap(Foo &rhs);
private:
Foo(const Foo&);
// snip: swap code
};
void swap(Foo& lhs, Foo& rhs);
Run Code Online (Sandbox Code Playgroud)
如果我没有复制构造函数,是否有意义实现operator = by value和swap?它应该防止复制我的类对象Foo但允许移动.
这个类是不可复制的,所以我不能复制构造或复制分配它.
我用这个测试了我的代码,它似乎有我想要的行为.
#include <utility>
#include <cstdlib>
using std::swap;
using std::move;
class Foo{
public: Foo():a(rand()),b(rand()) {}
Foo(Foo && rhs):a(rhs.a), b(rhs.b){rhs.a=rhs.b=-1;}
Foo& operator=(Foo rhs){swap(*this,rhs);return *this;}
friend void swap(Foo& lhs, Foo& rhs){swap(lhs.a,rhs.a);swap(lhs.b,rhs.b);}
private:
//My compiler doesn't yet implement deleted constructor
Foo(const Foo&);
private:
int a, b;
};
Foo make_foo()
{
//This is potentially much more complicated
return Foo();
}
int main(int, char*[])
{
Foo f1;
Foo f2 = make_foo(); //move-construct
f1 = make_foo(); //move-assign
f2 = move(f1);
Foo f3(move(f2));
f2 = f3; // fails, can't copy-assign, this is wanted
Foo f4(f3); // fails can't copy-construct
return 0;
}
Run Code Online (Sandbox Code Playgroud)
移动和交换确实是合理的.如果禁用复制构造函数,那么调用此函数的唯一方法是使用移动构造函数构造参数.这意味着如果你写
lhs = rhs; // Assume rhs is an rvalue
Run Code Online (Sandbox Code Playgroud)
然后,operator =将使用移动构造函数初始化参数的构造函数,清空rhs并将参数设置为旧值rhs.然后呼吁swap交换lhs旧的价值和rhs旧的价值,留下lhs持有rhs的旧价值.最后,参数的析构函数触发,清理lhs旧的记忆.作为一个注释,这实际上不是移动和交换的复制和交换.
那说,你现在拥有的是不正确的.std::swap内部的默认实现将尝试使用移动构造函数来移动元素,这会导致无限递归循环.你必须超载std::swap以使其正常工作.
有关更多信息,请参阅此问题及其对"四分之一规则"的讨论.
希望这可以帮助!
| 归档时间: |
|
| 查看次数: |
1829 次 |
| 最近记录: |