Когда использовать семантику перемещения по ссылкам или уникальным указателям? - PullRequest
2 голосов
/ 14 июля 2020

Я новичок в C ++ и только изучаю семантику перемещения. Итак, насколько я понимаю, с помощью конструктора перемещения я могу сделать что-то вроде

MyObj obj1;
MyObj obj2 = std:move(obj1);

И мы должны определить наш собственный конструктор перемещения, который очищает obj1 et c.

Кажется вместо этого мы можем использовать obj2 как ссылку на obj1, если мы знаем, что obj1 не будет уничтожен до того, как будет использовано obj2. Но иначе, не можем ли мы просто использовать вместо этого unique_ptr? Таким образом, мы просто создаем уникальный указатель для obj1, а затем передаем этот указатель вместо того, чтобы пытаться переместить объект?

Есть ли какие-то случаи, которые я не рассматриваю?

1 Ответ

3 голосов
/ 14 июля 2020

Из приведенного вами примера я согласен, что вы можете использовать здесь ссылку или даже shared_ptr, но это действительно зависит от вашего варианта использования.

Однако семантика перемещения очень удобна для выражения смены владельца . Например, предположим, что obj1 - это некоторый ресурс (подумайте о подключении к базе данных, файл, который вы тоже пишете, и т. Д. c). А теперь рассмотрим следующее:

int func1() {
   MyObj obj1;
   // do something with obj1
   func2(std::move(obj1));
   // do some other stuff without obj1
   return 0;
}

в третьей строке func1 мы передаем право собственности на obj1 func2. После этой строки func1 больше не владеет obj1 и не должен его использовать, тогда как func2 может делать все, что ему нужно, с obj1.

Это особенно полезно для ресурсов, таких как файл , где func1 может что-то сделать с файлом, а затем func2 сделать что-то еще. Использование std::move похоже на контракт, согласно которому func1 больше не будет изменять этот объект. Это предотвращает возможность func1 перезаписать работу, выполненную func2

.
...