Вот рекомендуемый шаблон:
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;
}
Естественно, если элементы данных являются скалярными типами, 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_))
{
}
И если вы хотите обобщить типы, которые не имеют конструкторов перемещения, но имеют построенное состояние по умолчанию без использования ресурсовВы можете:
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();
}
Я рекомендую упорядочить эти операторы в том же порядке, в котором они объявлены как члены данных в определении класса array2D
.И я не нахожу ничего плохого в повторении списка инициализаторов в теле.Это является необходимым и вторым шагом.Нет необходимости подмести его под ковром.