До C ++ 11 я видел такой код:
class Car {
public:
Car() {}
private:
Car(const Car&);
Car& operator=(const Car&);
};
Для C ++ 11 (и позже) я вижу такой код:
class Car {
public:
Car() {}
private:
Car(const Car&) = delete;
Car& operator=(const Car&) = delete;
};
Они ведут себя одинаково? Если нет, пожалуйста, объясните.
Ref: https://ariya.io/2015/01/c-class-and-preventing-object-copy
Они похожи во многих отношениях, но отличаются в некоторых других.
Рассмотрим следующее внешний Код пытается скопировать объекты класса:
int main() {
Car c;
Car other{c};
}
Обе эти версии приведут к сбою кода выше. На этом этапе, однако, разработчик будет смотреть на интерфейс, чтобы понять, почему. С delete
версия, очевидно, что Car
не предназначался для копирования. С private
версия, (по крайней мере, без комментариев), это ставит под сомнение, возможно, был помещен конструктор копирования в private
раздел случайно.
Теперь рассмотрим член Код пытается скопировать объекты класса:
void Car::foo() {
Car c;
Car other{c};
}
delete
версия терпит неудачу как прежде. private
версия является ошибкой ссылки. Это вызывает еще большее сомнение — нередко забывают определять метод, который был объявлен. Возможно, это то, что здесь произошло? delete
версия не имеет этой проблемы.
редактировать Скотт Мейерс обсуждает это в пункте 11 Эффективный Современный C ++ Предпочитаю удаленные функции частным неопределенным.
=delete
даст более значимые сообщения об ошибках. Сообщение об ошибке об удаленной функции говорит вам, что она не существует, и никто не может создать объект с указанным конструктором. Сказать, что это личное, не дает этой информации — просто говорит, что звонящий не может позвонить, не то, что никто не может.
Кроме того, удаленный конструктор не будет вести себя иначе, если вызывается изнутри / снаружи класса (поскольку частные конструкторы могут быть вызваны изнутри класса).
Обратите внимание, что два опубликованных фрагмента выдают одну и ту же ошибку, например:
‘Car (const Car)&) ‘является частной в этом контексте
Это потому, что вы определили методы-члены как закрытые в обоих случаях.
Если вы хотите оценить различия, вы должны иметь delete
d конструктор копирования и оператор копирования, то есть:
class Car {
public:
Car() {}
// private: <-- this should not be here
Car(const Car&) = delete;
Car& operator=(const Car&) = delete;
};
Таким образом, вы будете проинформированы о том, что эти методы явно и намеренно удалены:
использование удаленной функции ‘Car (const Car)&)»
Установка их как приватных не говорит явно Я хочу удалить их.
Например, это можно было сделать, если вы хотите сила пользователи вашего класса используют фабричный метод для создания экземпляров этого класса.
Во всяком случае, (уже не так) новые функции не бесплатны, и использование их не по назначению не даст ожидаемого выгоды.
Car& operator=(const Car&) = delete;
явно выражает «копирование запрещено».
= delete;
может также использоваться для любой функции, как описано на Бьярне блог:
struct Z {
// ...
Z(long long); // can initialize with an long long
Z(long) = delete; // but not anything less
};