Подтвердить что ты не робот

Правильное использование `= delete` для методов в классах

Является ли следующая snipplet правильной для un-define всех иначе сгенерированных методов и конструкторов для класса?

struct Picture {

  // 'explicit': no accidental cast from string to Picture
  explicit Picture(const string &filename) { /* load image from file */ }

  // no accidental construction, i.e. temporaries and the like
  Picture() = delete;

  // no copy
  Picture(const Picture&) = delete;

  // no assign
  Picture& operator=(const Picture&) = delete;

  // no move
  Picture(Picture&&) = delete;

  // no move-assign
  Picture& operator=(Picture&&) = delete; // return type correct?
};

Это удаляет каждую реализацию компилятора по умолчанию и оставляет только деструктор, верно? Без него класс был бы (почти) непригодным для использования, я думаю, но я мог бы удалить его также, правильно?

Правильно ли возвращен тип Picture& для параметра move-assign operator=(Picture&&)? Это имеет значение, если я написал Picture&& для возвращаемого типа?

4b9b3361

Ответ 1

В дополнение к ответу Xeo:

Да, все правильно. Если бы вы хотели, вы могли бы удалить все удаленные элементы, но удаленный экземпляр копии и удаленное назначение копии и иметь тот же эффект:

struct Picture {  // Also ok

  // 'explicit': no accidental cast from string to Picture
  explicit Picture(const string &filename) { /* load image from file */ }

  // no copy
  Picture(const Picture&) = delete;

  // no assign
  Picture& operator=(const Picture&) = delete;
};

Явное объявление конструктора копирования запрещает неявное генерирование конструктора по умолчанию, перемещает конструктор и перемещает элементы назначения. Если эти члены явно удалены, это вопрос вкуса. Некоторые из них, вероятно, считают это хорошей документацией. Другие могут считать это слишком многословным.

Ответ 2

Кажется, мне хорошо. Возвращаемое значение operator= должно быть нормальной ссылкой, даже если объект построен из ссылки rvalue. Это связано с тем, что вы не можете просто скомпилировать lvalue (*this) для rvalue.
И он должен взять эту ссылку rvalue для не-const Picture& operator=(Picture&&). Как бы вы переместились из постоянного объекта?;)