Сгенерированные операторы копирования и перемещения?
В настоящее время я читаю книгу " Эффективное современное С ++" от Скотта Мейерса, и теперь я нахожусь по адресу: Пункт 17: Понимание генерации функций специальных членов.
Мое недоразумение исходит из следующей части (обоснование):
Две операции копирования независимы: объявление одной не мешает компиляторам генерировать другую. Поэтому, если вы объявляете конструктор копирования, но не используете оператор назначения копирования, а затем пишете код, который требует назначения копирования, компиляторы сгенерируют для вас оператор назначения копирования. Точно так же, если вы объявляете оператор присваивания копии, но не конструктор копирования, но ваш код требует построения копии, компиляторы сгенерируют конструктор копирования для вас. Это было верно в C++98, и это все еще верно в C++11.
Две операции перемещения не являются независимыми. Если вы объявите одно из них, это не позволит компиляторам генерировать другое. Смысл в том, что если вы объявляете, скажем, конструктор перемещения для вашего класса, вы указываете, что есть кое-что о том, как должна быть реализована конструкция перемещения, которая отличается от перемещения по умолчанию для каждого элемента, генерируемого компиляторами. И если что-то не так с конструкцией перемещения по элементам, вероятно, что-то не так с назначением движения по элементам. Таким образом, объявление конструктора перемещения предотвращает создание оператора присваивания перемещения, а объявление оператора назначения перемещения не позволяет компиляторам создавать конструктор перемещения.
Я думаю, что часть обоснования может быть применена к конструктору копирования и паре операторов присваивания копии, не так ли? Поэтому, если я объявляю конструктор копирования, я указываю им, что копия по умолчанию для каждого элемента мне не подходит. И если я скажу это, то, вероятно, оператор присвоения копии должен быть также определен пользователем.
Я думаю, что это отличная книга, но на данный момент это обоснование не ясно для меня. Пожалуйста, помогите и объясните мне это. Благодарю.
1 ответ
Я думаю, что часть обоснования может быть применена к конструктору копирования и паре операторов присваивания копии, не так ли?
Абсолютно. Стандарт с вами согласен. В [class.copy]:
Если определение класса не объявляет явно конструктор копирования, неявный неявно объявляется. Если определение класса объявляет конструктор перемещения или оператор присваивания перемещения, неявно объявленный конструктор копирования определяется как удаленный; в противном случае он определяется как дефолтный (8.4). Последний случай считается устаревшим, если в классе есть объявленный пользователем оператор копирования или объявленный пользователем деструктор.
А также:
Если определение класса явно не объявляет оператор присваивания копии, он объявляется неявно. Если определение класса объявляет конструктор перемещения или оператор присваивания перемещения, неявно объявленный оператор присваивания копии определяется как удаленный; в противном случае он определяется как дефолтный (8.4). Последний случай считается устаревшим, если в классе имеется объявленный пользователем конструктор копирования или объявленный пользователем деструктор.
Конечно, существует, вероятно, много существующего кода, который сломался бы, если бы "последние случаи", о которых идет речь, были незамедлительно устранены, поэтому Стандарт перешел в первую очередь к устареванию и удалит их только в некотором произвольно отдаленном месте в будущем.
С другой стороны, даже давно устаревшие и удаленные функции имеют возможность долго оставаться в прошлом. подобно char * s = "MyString";