Конструктор Move не должен инициализировать свои члены класса и базовые классы, используя семантику копирования
Конструктор перемещения не должен инициализировать свои члены класса и базовые классы с помощью семантики копирования.
В C++ операции перемещения переносят владение ресурсами, а не дублируют сами ресурсы из исходного объекта в целевой объект. Поскольку конструкторы перемещения не дублируют ресурсы, эти конструкторы быстрее, чем конструкторы копирования. Рассмотрим этот код, где объект CopyTarget
копируется, и объект MoveTarget
сконструирован на перемещение из объекта Source
.
class BigData{ //... BigData(BigData&&){ //Move Constructor //... } copy constructed BigData(const BigData&){ //Copy Constructor //... } private: std::map<int, std::string> BigBook; }; int main(){ BigData Source; BigData CopyTarget = Source; BigData Movetarget = std::move(Source); //... }
При копировании-построении CopyTarget
компилятор дублирует ресурс Source::BigBook
от Source
на CopyTarget
. После создания копии оба этих объектов имеют копию ресурса BigBook
. При построении Movetarget
компилятор передает право собственности на ресурс Source::BigBook
на MoveTarget
. Поскольку move-construction не дублирует ресурс физически, это быстрее, чем copy-construction.
Move-construction является стратегией оптимизации. Вы ожидаете, что move-construction будет дешевле и быстрее, чем copy-construction. Инициализирующие копирование представители данных и базовые классы могут сделать конструктор перемещения медленным и неэффективным, что снижает эффективность программы. Разработчики ожидают, что move-construction использует только семантику перемещения. Неожиданное использование семантики копирования в конструкторах перемещения может привести к утечкам ресурсов и несогласованности в будущем развитии. При создании конструкторов перемещения инициализируйте представители данных и базовые классы с помощью семантики перемещения. Можно копировать-инициализировать скалярные представители данных, не нарушая это правило.
Вы можете использовать std::move()
для реализации семантики перемещения в коде. Когда вы используете std::move()
чтобы переместить объекты, объявите объекты или представители данных без квалификатора const
. Для получения дополнительной информации смотрите AUTOSAR C++14 Rule A18-9-3
.
Когда конструктор перемещения не использует семантику перемещения для инициализации нескалярных представителей данных и базовых классов, Polyspace® помечает его объявление. Например, если конструктор перемещения инициализирует базовый класс с помощью конструктора по умолчанию вместо конструктора перемещения, Polyspace помечает объявление конструктора перемещения.
Если вы ожидаете нарушения правил, но не видите его, обратитесь к разделу «Стандартные нарушения кодирования не отображаются».
Группа: Специальные функции представителей |
Категория: Необходимый, Автоматизированный |