#c #move-constructor
Вопрос:
Я создал следующий класс:
class CList
{
private:
Cust *custArray{new Cust [1]};
size_t arrayCap{1};
size_t used{0};
// also, the number of used cells
public:
CList() = defau<
CList(CListamp;amp;);
class Cust
{
private:
const char *name;
const char *email;
size_t id;
public:
Cust()
{
}
Cust(const char *_name, const char *_email, size_t _id)
{
name = _name;
email = _email;
id = _id;
}
};
Мне нужна помощь в реализации CList(CListamp;amp;)
конструктора перемещения. Будет ли он просто создавать копию передаваемого объекта?
Комментарии:
1. Конструкторы перемещения, как там сказано, ничего не копируют. Они перемещают значения, оставляя переданный объект в неопределенном состоянии.
2.
CList(CListamp;amp; x) : custArray{std::exchange(x.custArray, nullptr}, arrayCap{std::exchange(x.arrayCap, 0)}, used{std::exchange(x.used, 0)} { }
3. Не выделяйте память вручную, если в этом нет необходимости. Если вы используете вектор, вы могли бы:
class CList { private: std::vector<Cust> custArray; public: CList() = defau< CList(CListamp;amp;) = defau< };
Ответ №1:
Конструктор перемещения обычно передает ресурсы новому объекту, а не копирует их. Такая передача обычно включает копирование только дескриптора (указателя, файлового дескриптора или чего-либо еще), а не любого ресурса, на который ссылается дескриптор. Как только это будет сделано, конструктор гарантирует, что перемещенный объект не ссылается ни на какие ресурсы (т. Е. дескрипторы являются нулевыми или недопустимыми или какими-либо другими). Например:
CList(CListamp;amp; other) {
custArray = other.custArray; // copy the handle
arrayCap = other.arrayCap; // copy supporting information
used = other.used; // copy supporting information
other.custArray = nullptr; // zero out the old handle
}
Вероятно, вам следует использовать std::exchange
в реальном коде. Что еще более важно, однако, в реальном коде вы должны использовать std::vector
вместо массива, выделенного вручную, что делает написанный от руки конструктор перемещения совершенно ненужным.
Комментарии:
1. Может
if (this == amp;other) return;
ли это когда-нибудь случиться? Объект только сейчас находится в стадии строительства, что означает, что он не может быть использован для перемещения в себя, если вы не напишетеCList foo = std::move(foo);
2. Это выглядит точно так же, как перегрузка оператора присваивания
operator=
. Есть ли какая — то разница между этими двумя?3. @joseph Это кажется точно таким же, как перегрузка оператора присваивания operator= Нет, эти вещи очень разные.
4. @джозеф Есть существенные различия. Конструкторы создают объекты, которых раньше не существовало. Назначение — это изменение состояния существующего объекта, которому, возможно, придется сначала очистить старое состояние, прежде чем переходить в новое. Назначение обычно также возвращает ссылку на себя. Однако между операторами перемещения и назначения перемещения происходит примерно то же самое, что и с перемещенным объектом.
5. Написание конструктора перемещения, а также оператора назначения перемещения обычно выполняются вместе. Если одно существует, то другое, вероятно, тоже желательно.