fre*_*low 12 c++ move-constructor move-semantics c-preprocessor c++11
在玩具类的移动构造函数的实现过程中,我注意到了一种模式:
array2D(array2D&& that)
{
data_ = that.data_;
that.data_ = 0;
height_ = that.height_;
that.height_ = 0;
width_ = that.width_;
that.width_ = 0;
size_ = that.size_;
that.size_ = 0;
}
Run Code Online (Sandbox Code Playgroud)
模式显然是:
member = that.member;
that.member = 0;
Run Code Online (Sandbox Code Playgroud)
所以我写了一个预处理器宏来减少冗长和容易出错:
#define STEAL(member) member = that.member; that.member = 0;
Run Code Online (Sandbox Code Playgroud)
现在实现如下:
array2D(array2D&& that)
{
STEAL(data_);
STEAL(height_);
STEAL(width_);
STEAL(size_);
}
Run Code Online (Sandbox Code Playgroud)
这有什么缺点吗?有没有更清洁的解决方案,不需要预处理器?
How*_*ant 12
这是推荐的模式:
array2D(array2D&& that)
: data_(std::move(that.data_)),
height_(std::move(that.height_)),
width_(std::move(that.width_)),
size_(std::move(that.size_))
{
that.data_ = 0;
that.height_ = 0;
that.width_ = 0;
that.size_ = 0;
}
Run Code Online (Sandbox Code Playgroud)
当然,如果数据成员是标量类型,std::move则不需要.但是如果你正在复制这种模式,那么move无论如何都要包含它是有帮助的,这样当成员数据不是标量时,std::move就不会忘记.
此外,如果成员数据具有实际的移动构造函数,那么您可以简单地省略正文:
array2D(array2D&& that)
: data_(std::move(that.data_)),
height_(std::move(that.height_)),
width_(std::move(that.width_)),
size_(std::move(that.size_))
{
}
Run Code Online (Sandbox Code Playgroud)
如果要概括为没有移动构造函数的类型,但确实具有无资源的默认构造状态,则可以:
array2D(array2D&& that)
: data_(std::move(that.data_)),
height_(std::move(that.height_)),
width_(std::move(that.width_)),
size_(std::move(that.size_))
{
that.data_ = Data();
that.height_ = Height();
that.width_ = Width();
that.size_ = Size();
}
Run Code Online (Sandbox Code Playgroud)
我建议按照它们在array2D类定义中声明为数据成员的顺序排序这些语句.而且我发现在身体中重复初始化列表并没有错.这是必要的第二步.没有必要把它扫到地毯下面.
如何使用template:
template<typename T> inline
void MOVE(T &dst, T &src)
{
dst = src;
src = 0;
}
Run Code Online (Sandbox Code Playgroud)
用法:
MOVE(data_, that.data_);
Run Code Online (Sandbox Code Playgroud)
@Fred,从您的评论中,如果您想避免两次提及数据成员,那么:
#define STEAL(X) MOVE(X, that.X)
Run Code Online (Sandbox Code Playgroud)
用法:
STEAL(data_);
Run Code Online (Sandbox Code Playgroud)
将您自己的成员初始化为默认值,然后swap.
array2D(array2D&& that)
{
data_ = 0;
height_ = 0;
width_ = 0;
size_ = 0;
this->swap(that);
}
Run Code Online (Sandbox Code Playgroud)
更干净(如果您的编译器支持它)
array2D(array2D&& that)
: array2D() {
this->swap(that);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
702 次 |
| 最近记录: |