Правило 5, когда код перемещения совпадает с кодом копирования? - PullRequest
2 голосов
/ 06 января 2020

Скажем, в моем классе только один участник, int. Нет смысла «перемещать» этот int вместо его копирования. Поэтому мне нужен конструктор перемещения и оператор присваивания перемещения, которые просто выполняют ту же функцию, что и их двоюродные братья по копированию?

Ответы [ 2 ]

2 голосов
/ 06 января 2020

Если ваш класс не делает ничего особенного с членами-копиями или деструктором, лучше всего не объявлять ни одного из них:

class A
{
    int i_;
public:
    // Special members
    A() : i_{0} {}

    // Other constructors
    explicit A(int i) : i_{i} {}

    // ...
};

Это дает сгенерированному компилятором классу копию и перемещение членов ( и деструктор), которые такие же, как и для самого int.

Если ваш класс делает что-то особенное для деструктора или любого из членов копирования, и вы хотите, чтобы компилятор генерировал поведение для элементов перемещения, тогда Вы должны = default их. В противном случае у вас не будет элементов перемещения, что, вероятно, именно то, что вам нужно (при копировании из rvalues ​​используются члены копирования).

class A
{
    int i_;
public:
    // Special members
    A() : i_{0} {}
    A(const& A a);                 // do something special
    A(A&&) = default;              // just copy the int
    A& operator=(A&&) = default;   // just copy the int

    // Other constructors
    explicit A(int i) : i_{i} {}

    // ...
};

Обратите внимание, что для вашего класса было бы весьма необычно вести себя по-другому при копировании из lvalue и копирование из rvalue, как описано с кодом выше. Я не могу сразу придумать мотивирующий вариант использования для такого кода.

Если вы хотите иметь возможность копировать значения вашего класса, но без специальной обработки «переместить» (просто используйте копирование), тогда типичная формулировка:

class A
{
    int i_;
public:
    // Special members
    A() : i_{0} {}
    A(const& A a);             // do something special for lvalues and rvalues
    A& operator=(const& A a);  // do something special for lvalues and rvalues

    // Other constructors
    explicit A(int i) : i_{i} {}

    // ...
};

Теперь клиенты все еще могут «перемещаться» A, но эти перемещения просто копируются в соответствии с элементами копирования A.

0 голосов
/ 06 января 2020

Если вы не определили свой конструктор перемещения, компилятор объявляет его, если выполняются следующие условия

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

Так что, если вы нарушите предыдущие условия, компилятор не предоставит ctor перемещения, и cpy будет вызываться вместо него.

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