Move constructors
Материал из cppreference.com
![]() |
Эта страница была переведена автоматически с английской версии вики используя Переводчик Google.
Перевод может содержать ошибки и странные формулировки. Наведите курсор на текст, чтобы увидеть оригинал. Вы можете помочь в исправлении ошибок и улучшении перевода. Для инструкций перейдите по ссылке. Щёлкните здесь, чтобы увидеть английскую версию этой страницы |
Движение конструктор класса
T
не является шаблоном конструктор, первый параметр T&&, const T&&, volatile T&&, или const volatile T&&, и либо нет других параметров, или остальные параметры имеют значения по умолчанию. Типа с общественностью конструктор шаг MoveConstructible
.Оригинал:
A move constructor of class
T
is a non-template constructor whose first parameter is T&&, const T&&, volatile T&&, or const volatile T&&, and either there are no other parameters, or the rest of the parameters all have default values. A type with a public move constructor is MoveConstructible
.Текст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
Содержание |
[править] Синтаксис
class_name ( class_name && )
|
(1) | (начиная с C++11) | |||||||
class_name ( class_name && ) = default;
|
(2) | (начиная с C++11) | |||||||
class_name ( class_name && ) = delete;
|
(3) | (начиная с C++11) | |||||||
[править] Объяснение
# Типичное объявление ход конструктора
Оригинал:
# Typical declaration of a move constructor
Текст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
# Принудительное движение конструктор, генерируемых компилятором
Оригинал:
# Forcing a move constructor to be generated by the compiler
Текст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
# Как избежать неявного конструктора ход
Оригинал:
# Avoiding implicit move constructor
Текст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
Этот шаг конструктор вызывается всякий раз, когда объект инициализируется из xvalue того же типа, который включает в себя
Оригинал:
The move constructor is called whenever an object is initialized from xvalue of the same type, which includes
Текст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
- проходящий аргумент функции: f(std::move(a));, где
a
имеет типT
иf
является void f(T t)Оригинал:Текст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда. - Функция возврата: return a; внутри функции, такие как T f(), где
a
имеет типT
, которая имеет ход конструктор.Оригинал:function return: return a; inside a function such as T f(), wherea
is of typeT
which has a move constructor.Текст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
Переместить конструкторы обычно "украсть" ресурсы, удерживаемые аргумент (например, указатели на динамически выделяемых объектов, дескрипторов файлов, TCP сокеты, потоки ввода / вывода, выполняемых потоков и т.д.), а не сделать их копии, и оставить аргумент в некоторые действительные, но в остальном неопределенном состоянии. Например, переход от std::string или std::vector оказывается пустым аргументом.
Оригинал:
Move constructors typically "steal" the resources held by the argument (e.g. pointers to dynamically-allocated objects, file descriptors, TCP sockets, I/O streams, running threads, etc), rather than make copies of them, and leave the argument in some valid but otherwise indeterminate state. For example, moving from a std::string or from a std::vector turns the argument empty.
Текст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
[править] Неявно заявил ходу конструктор
Если пользователь не определенных конструкторов ходу предназначены для классового типа (struct, class, или union), и все из следующих условий:
Оригинал:
If no user-defined move constructors are provided for a class type (struct, class, or union), and all of the following is true:
Текст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
- нет пользователем объявленный конструктор копииОригинал:there are no user-declared copy constructorsТекст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда. - нет пользователей заявили операторы копия заданияОригинал:there are no user-declared copy assignment operatorsТекст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда. - нет пользователей заявили операторы ходу назначенияОригинал:there are no user-declared move assignment operatorsТекст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда. - нет пользователем объявленной destructursОригинал:there are no user-declared destructursТекст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда. - неявно объявлен ход конструктора не будут определены как удаленныеОригинал:the implicitly-declared move constructor would not be defined as deletedТекст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
то компилятор будет объявить ход конструктору
inline public
членом своего класса с подписью T::T(T&&)
Оригинал:
then the compiler will declare a move constructor as an
inline public
member of its class with the signature T::T(T&&)
Текст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
Класс может иметь несколько конструкторов движения, например, как T::T(const T&&) и T::T(T&&). Если некоторые пользовательские конструкторы движении присутствует, пользователь все еще может заставить поколения неявно движение конструктор с ключевым словом
default
.Оригинал:
A class can have multiple move constructors, e.g. both T::T(const T&&) and T::T(T&&). If some user-defined move constructors are present, the user may still force the generation of the implicitly declared move constructor with the keyword
default
.Текст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
[править] Удаленные неявно объявлен ход конструктора
Неявно объявлен дефолт или движение конструктор для класса
T
определяется как' удалены в любом из следующих условий:Оригинал:
The implicitly-declared or defaulted move constructor for class
T
is defined as deleted in any of the following is true:Текст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
-
T
имеет не статические данные пользователей, которые не могут быть перемещены (были удалены, недоступными или неоднозначных конструкторов ход)Оригинал:T
has non-static data members that cannot be moved (have deleted, inaccessible, or ambiguous move constructors)Текст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда. -
T
имеет прямое или виртуальный базовый класс, который не может быть перемещен (удалил, недоступными или неоднозначных конструкторов ход)Оригинал:T
has direct or virtual base class that cannot be moved (has deleted, inaccessible, or ambiguous move constructors)Текст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда. -
T
имеет прямое или виртуальный базовый класс с удаленных или недоступных деструкторОригинал:T
has direct or virtual base class with a deleted or inaccessible destructorТекст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда. -
T
имеет определенный пользователем конструктор ходу движения или оператора присваиванияОригинал:T
has a user-defined move constructor or move assignment operatorТекст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда. -
T
является объединением и имеет вариант член с нетривиальным конструктором копийОригинал:T
is a union and has a variant member with non-trivial copy constructorТекст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда. -
T
имеет не статические данные члена или прямой или виртуальной базы без движения конструктор, который не является тривиальным копируемой.Оригинал:T
has a non-static data member or a direct or virtual base without a move constructor that is not trivially copyable.Текст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
[править] Тривиальные конструктор ход
Неявно объявлен движение конструктор для класса
T
является тривиальной, если все следующие условия:Оригинал:
The implicitly-declared move constructor for class
T
is trivial if all of the following is true:Текст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
-
T
не имеет виртуальных функций-членовОригинал:T
has no virtual member functionsТекст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда. -
T
не имеет виртуальные базовые классыОригинал:T
has no virtual base classesТекст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда. - Этот шаг конструктора выбран для каждого прямого базы
T
тривиальноОригинал:The move constructor selected for every direct base ofT
is trivialТекст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда. - Этот шаг конструктора выбран для каждого нестатический тип класса (или массив типа класса) Член КЛУБА
T
тривиальноОригинал:The move constructor selected for every non-static class type (or array of class type) memeber ofT
is trivialТекст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
Тривиальным конструктором шаг конструктор, который выполняет те же действия, как тривиальный конструктор копирования, который делает копию объекта представления, как по std::memmove. Все типы данных, совместимые с языком C (POD типов) тривиально подвижный.
Оригинал:
A trivial move constructor is a constructor that performs the same action as the trivial copy constructor, that is, makes a copy of the object representation as if by std::memmove. All data types compatible with the C language (POD types) are trivially movable.
Текст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
[править] Неявно определенный ход конструктора
Если неявно объявлен движение конструктор не удаляется и не тривиально, оно определено (то есть, тела функции создается и компилируется) компилятором. Для union типа, неявно определенные движения конструктор копирует объект представления (как по std::memmove). Для не состоящих в профсоюзе типа класса (class и struct), движение конструктор выполняет полный член-мудрый шаг баз объекта и не статическим членам, по их порядка инициализации, используя прямой инициализации с аргументом xvalue.
Оригинал:
If the implicitly-declared move constructor is not deleted or trivial, it is defined (that is, a function body is generated and compiled) by the compiler. For union types, the implicitly-defined move constructor copies the object representation (as by std::memmove). For non-union class types (class and struct), the move constructor performs full member-wise move of the object's bases and non-static members, in their initialization order, using direct initialization with an xvalue argument.
Текст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
[править] Заметки
Для того, чтобы сильная гарантия исключения возможных, определяемых пользователем конструкторов движение не должно бросать исключения. В самом деле, стандартные контейнеры обычно полагаются на std::move_if_noexcept выбирать между перемещать и копировать, когда контейнер элементы должны быть переведены.
Оригинал:
To make strong exception guarantee possible, user-defined move constructors should not throw exceptions. In fact, standard containers typically rely on std::move_if_noexcept to choose between move and copy when container elements need to be relocated.
Текст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
Если оба копирования и перемещения конструкторы при условии, разрешение перегрузки выбирает движение конструктор, если аргумент RValue ( или prvalue, таких как безымянные временное или' xvalue таких, как результат std::move) , и выбирает конструктор копии, если аргумент' именующее (названный объект или функция / оператор возвращения именующее ссылка). Если только конструктор копии при условии, все аргументы категорий, выделите ее (пока она занимает ссылкой на константный, поскольку rvalues можно привязать к константные ссылки), что делает копирование резервной для перемещения, при движении остается недоступным.
Оригинал:
If both copy and move constructors are provided, overload resolution selects the move constructor if the argument is an rvalue (either prvalue such as a nameless temporary or xvalue such as the result of std::move), and selects the copy constructor if the argument is lvalue (named object or a function/operator returning lvalue reference). If only the copy constructor is provided, all argument categories select it (as long as it takes reference to const, since rvalues can bind to const references), which makes copying the fallback for moving, when moving is unavailable.
Текст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
Во многих ситуациях, перемещение конструкторы оптимизирована, даже если они будут производить наблюдаемые побочные эффекты, см. Копия элизии
Оригинал:
In many situations, move constructors are optimized out even if they would produce observable side-effects, see Копия элизии
Текст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
[править] Пример
Запустить этот код
#include <string> #include <iostream> struct A { std::string s; A() : s("test") {} A(const A& o) : s(o.s) { std::cout << "move failed!\n";} A(A&& o) : s(std::move(o.s)) {} }; A f(A a) { return a; } struct B : A { std::string s2; int n; // implicit move-contructor B::(B&&) // calls A's move constructor // calls s2's move constructor // and makes a bitwise copy of n }; struct C : B { ~C() {}; // destructor prevents implicit move }; struct D : B { D() {} ~D() {}; // destructor would prevent implicit move D(D&&) = default; // force a move ctor anyway }; int main() { std::cout << "Trying to move A\n"; A a1 = f(A()); // move-construct from rvalue temporary A a2 = std::move(a1); // move-construct from xvalue std::cout << "Trying to move B\n"; B b1; std::cout << "Before move, b1.s = \"" << b1.s << "\"\n"; B b2 = std::move(b1); // calls implicit move ctor std::cout << "After move, b1.s = \"" << b1.s << "\"\n"; std::cout << "Trying to move C\n"; C c1; C c2 = std::move(c1); // calls the copy constructor std::cout << "Trying to move D\n"; D d1; D d2 = std::move(d1); }
Вывод:
Trying to move A Trying to move B Before move, b1.s = "test" After move, b1.s = "" Trying to move C move failed! Trying to move D