я могу использовать std :: move с классом, который не предоставляет конструктор перемещения? - PullRequest
0 голосов
/ 30 мая 2018

У меня есть такой класс:

class myClass
{
    int x[1000];
 public:
     int &getx(int i)
    {
        return x[i];
    }
}

Обратите внимание, что я не предоставил здесь конструкцию перемещения.

, если я использую следующий код:

myClass A;
auto B=std::move(a);

перемещается ли A в B или, поскольку я не предоставил конструктор перемещения, A копируется в B?

Есть ли конструктор перемещения по умолчанию для объекта?Если да, то как это работает с указателями и динамически размещаемыми массивами?

Ответы [ 5 ]

0 голосов
/ 30 мая 2018

Есть ли конструктор перемещения по умолчанию для объекта?

Да, в вашем случае.Для любого типа T конструктор перемещения неявно объявляется, только если выполняются некоторые условия.Более подробную информацию можно найти на cpperference.com .

Если да, как он работает с указателями и динамически размещаемыми массивами?

По умолчаниюРеализация сделает мелкие копии указателей.Как следствие, более одного объекта будут указывать на динамически распределенные массивы.Это приведет к проблемам.См. Правило трех для получения дополнительной информации по этому вопросу.

Если у вас есть указатели, которые указывают на динамически размещаемые массивы, вам необходимо:

  1. Предоставить явноопределенный конструктор копирования, который правильно работает с динамически размещаемыми массивами.Побочным эффектом этого будет то, что конструктор перемещения по умолчанию будет неявно удален.и / или
  2. Предоставьте явно определенный конструктор перемещения, в котором вы соответствующим образом перемещаете владельца динамически распределенных массивов.
0 голосов
/ 30 мая 2018

Если для типа класса (struct, class или union) не заданы определяемые пользователем конструкторы перемещения, и все следующее верно:

  • Пользователь не существуетзаявленные конструкторы копирования.
  • Нет объявленных пользователем операторов назначения копирования.
  • Нет объявленных пользователем операторов назначения перемещения.
  • Нет деструкторов, объявленных пользователем

тогда компилятор объявит конструктор перемещения как неявный встроенный открытый член своего класса с подписью T :: T (T &&).

Цитата из cppreference

По сути, да, конструктор перемещения по умолчанию создается до тех пор, пока вы не определите конструктор копирования, перегрузку назначения копирования, перегрузку назначения перемещения или деструктор.В противном случае вы должны либо определить поведение самостоятельно, либо использовать: class_name ( class_name && ) = default; , который явно объявит версию конструктора перемещения по умолчанию.

0 голосов
/ 30 мая 2018

Ваш вопрос похож на этот .Обратите внимание, что std :: move просто является приведением.Ваше значение a будет приведено к rvalue-ссылке, но в вашем случае исходный объект не будет разграблен или разграблен.

Чтобы правильно использовать API или идиому, вы должныиспользуйте это для правильной вещи.Перемещение наиболее целесообразно, например, для объектов класса, где основная часть данных объекта размещена в куче.Такой объект легко воровать, и «движение» может оставить ворованный объект в четко определенном состоянии.Каноническим примером может быть, например, некоторый тип строкового класса со строковыми данными в куче.

Что бы вы хотели, чтобы произошло?Предположим, a является локальной переменной в некоторой функции, т.е. предположим, что a находится в стеке.Предположим, что b является глобальной или файловой областью действия или анонимной переменной пространства имен, т.е. не в стеке.Что бы вы хотели, чтобы произошло при переходе с a на b ?

Для струн воровство имеет смысл.Для вашего случая воровство бессмысленно.

0 голосов
/ 30 мая 2018

Несмотря на то, что вы не предоставили явный конструктор перемещения, компилятор предоставил вам неявный конструктор перемещения.

Если определение класса X явно не объявляет конструктор перемещения, он будет неявно объявленпо умолчанию, если и только если

  • X не имеет объявленного пользователем конструктора копирования, а
  • X не имеет объявленного пользователем оператора копирования,
  • X не имеет объявленного пользователем оператора назначения перемещения,
  • X не имеет объявленного пользователем деструктора, и
  • конструктор перемещения не будет неявно определен как удаленный.

Итак, ответ на ваш вопрос: нет, A не копируется в B.

Не ясно, что вы задаете в других вопросах.Пожалуйста, уточните подробнее.

0 голосов
/ 30 мая 2018

Конструктор Move генерируется для вашего класса, поскольку вы не определяете какой-либо метод, который избегает его генерации (как определяемый пользователем деструктор или конструктор копирования)

Автоматически сгенерированный конструктор перемещения будет перемещать каждого члена.Для int[1000] это эквивалентно копированию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...