Правильное использование `= delete` для методов в классах - PullRequest
31 голосов
/ 16 апреля 2011

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

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-assignment operator=(Picture&&)?Имеет ли значение, если я написал Picture&& для типа возвращаемого значения?

Ответы [ 2 ]

27 голосов
/ 16 апреля 2011

В дополнение к ответу 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;
};

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

3 голосов
/ 16 апреля 2011

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

...