Пространства имён
Варианты
Действия

Move constructors

Материал из cppreference.com
< cpp‎ | language

 
 
Язык С++
Общие темы
Управление программой
Операторы условного выполнения
Операторы повторения
Операторы перехода
Функции
объявление функции
объявление лямбда-функции
шаблон функции
спецификатор inline
спецификаторы исключений (устарело)
спецификатор noexcept (C++11)
Исключения
Пространства имён
объявление пространства имён
псевдонимы пространства имён
Типы
спецификатор decltype (C++11)
Спецификаторы
cv-спецификаторы
спецификаторы продолжительности хранения
спецификатор constexpr (C++11)
спецификатор auto (C++11)
спецификатор alignas (C++11)
Инициализация
Литералы
Выражения
Утилиты
Типы
typedef-объявление
объявление псевдонима типа (C++11)
атрибуты (C++11)
Приведения типов
неявные преобразования
const_cast-преобразование
static_cast-преобразование
dynamic_cast-преобразование
reinterpret_cast-преобразование
C-подобное и функциональное приведение типов
Выделение памяти
Классы
Особые свойства классовых функций
Специальные функции-члены
Шаблоны
шаблон класса
шаблон функции
специализация шаблона
упакованные параметры (C++11)
Разное
Ассемблерные вставки
 
Движение конструктор класса 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 Translate.
Вы можете проверить и исправить перевод. Для инструкций кликните сюда.

Содержание

[править] Синтаксис

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 Translate.
Вы можете проверить и исправить перевод. Для инструкций кликните сюда.
# Принудительное движение конструктор, генерируемых компилятором
Оригинал:
# Forcing a move constructor to be generated by the compiler
Текст был переведён автоматически через Google Translate.
Вы можете проверить и исправить перевод. Для инструкций кликните сюда.
# Как избежать неявного конструктора ход
Оригинал:
# Avoiding implicit move constructor
Текст был переведён автоматически через Google Translate.
Вы можете проверить и исправить перевод. Для инструкций кликните сюда.
Этот шаг конструктор вызывается всякий раз, когда объект инициализируется из xvalue того же типа, который включает в себя
Оригинал:
The move constructor is called whenever an object is initialized from xvalue of the same type, which includes
Текст был переведён автоматически через Google Translate.
Вы можете проверить и исправить перевод. Для инструкций кликните сюда.
  • инициализации, T a = std::move(b); или T a(std::move(b));, где Ь типа T
    Оригинал:
    initialization, T a = std::move(b); or T a(std::move(b));, where b is of type T
    Текст был переведён автоматически через Google Translate.
    Вы можете проверить и исправить перевод. Для инструкций кликните сюда.
  • проходящий аргумент функции: f(std::move(a));, где a имеет тип T и f является void f(T t)
    Оригинал:
    function argument passing: f(std::move(a));, where a is of type T and f is void f(T t)
    Текст был переведён автоматически через Google Translate.
    Вы можете проверить и исправить перевод. Для инструкций кликните сюда.
  • Функция возврата: return a; внутри функции, такие как T f(), где a имеет тип T, которая имеет ход конструктор.
    Оригинал:
    function return: return a; inside a function such as T f(), where a is of type T which has a move constructor.
    Текст был переведён автоматически через Google Translate.
    Вы можете проверить и исправить перевод. Для инструкций кликните сюда.
Переместить конструкторы обычно "украсть" ресурсы, удерживаемые аргумент (например, указатели на динамически выделяемых объектов, дескрипторов файлов, 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 Translate.
Вы можете проверить и исправить перевод. Для инструкций кликните сюда.

[править] Неявно заявил ходу конструктор

Если пользователь не определенных конструкторов ходу предназначены для классового типа (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 Translate.
Вы можете проверить и исправить перевод. Для инструкций кликните сюда.
  • нет пользователем объявленный конструктор копии
    Оригинал:
    there are no user-declared copy constructors
    Текст был переведён автоматически через Google Translate.
    Вы можете проверить и исправить перевод. Для инструкций кликните сюда.
  • нет пользователей заявили операторы копия задания
    Оригинал:
    there are no user-declared copy assignment operators
    Текст был переведён автоматически через Google Translate.
    Вы можете проверить и исправить перевод. Для инструкций кликните сюда.
  • нет пользователей заявили операторы ходу назначения
    Оригинал:
    there are no user-declared move assignment operators
    Текст был переведён автоматически через Google Translate.
    Вы можете проверить и исправить перевод. Для инструкций кликните сюда.
  • нет пользователем объявленной destructurs
    Оригинал:
    there are no user-declared destructurs
    Текст был переведён автоматически через Google Translate.
    Вы можете проверить и исправить перевод. Для инструкций кликните сюда.
  • неявно объявлен ход конструктора не будут определены как удаленные
    Оригинал:
    the implicitly-declared move constructor would not be defined as deleted
    Текст был переведён автоматически через Google Translate.
    Вы можете проверить и исправить перевод. Для инструкций кликните сюда.
то компилятор будет объявить ход конструктору 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 Translate.
Вы можете проверить и исправить перевод. Для инструкций кликните сюда.
Класс может иметь несколько конструкторов движения, например, как 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 Translate.
Вы можете проверить и исправить перевод. Для инструкций кликните сюда.

[править] Удаленные неявно объявлен ход конструктора

Неявно объявлен дефолт или движение конструктор для класса T определяется как' удалены в любом из следующих условий:
Оригинал:
The implicitly-declared or defaulted move constructor for class T is defined as deleted in any of the following is true:
Текст был переведён автоматически через Google Translate.
Вы можете проверить и исправить перевод. Для инструкций кликните сюда.
  • T имеет не статические данные пользователей, которые не могут быть перемещены (были удалены, недоступными или неоднозначных конструкторов ход)
    Оригинал:
    T has non-static data members that cannot be moved (have deleted, inaccessible, or ambiguous move constructors)
    Текст был переведён автоматически через Google Translate.
    Вы можете проверить и исправить перевод. Для инструкций кликните сюда.
  • T имеет прямое или виртуальный базовый класс, который не может быть перемещен (удалил, недоступными или неоднозначных конструкторов ход)
    Оригинал:
    T has direct or virtual base class that cannot be moved (has deleted, inaccessible, or ambiguous move constructors)
    Текст был переведён автоматически через Google Translate.
    Вы можете проверить и исправить перевод. Для инструкций кликните сюда.
  • T имеет прямое или виртуальный базовый класс с удаленных или недоступных деструктор
    Оригинал:
    T has direct or virtual base class with a deleted or inaccessible destructor
    Текст был переведён автоматически через Google Translate.
    Вы можете проверить и исправить перевод. Для инструкций кликните сюда.
  • T имеет определенный пользователем конструктор ходу движения или оператора присваивания
    Оригинал:
    T has a user-defined move constructor or move assignment operator
    Текст был переведён автоматически через Google Translate.
    Вы можете проверить и исправить перевод. Для инструкций кликните сюда.
  • T является объединением и имеет вариант член с нетривиальным конструктором копий
    Оригинал:
    T is a union and has a variant member with non-trivial copy constructor
    Текст был переведён автоматически через Google Translate.
    Вы можете проверить и исправить перевод. Для инструкций кликните сюда.
  • T имеет не статические данные члена или прямой или виртуальной базы без движения конструктор, который не является тривиальным копируемой.
    Оригинал:
    T has a non-static data member or a direct or virtual base without a move constructor that is not trivially copyable.
    Текст был переведён автоматически через Google Translate.
    Вы можете проверить и исправить перевод. Для инструкций кликните сюда.

[править] Тривиальные конструктор ход

Неявно объявлен движение конструктор для класса T является тривиальной, если все следующие условия:
Оригинал:
The implicitly-declared move constructor for class T is trivial if all of the following is true:
Текст был переведён автоматически через Google Translate.
Вы можете проверить и исправить перевод. Для инструкций кликните сюда.
  • T не имеет виртуальных функций-членов
    Оригинал:
    T has no virtual member functions
    Текст был переведён автоматически через Google Translate.
    Вы можете проверить и исправить перевод. Для инструкций кликните сюда.
  • T не имеет виртуальные базовые классы
    Оригинал:
    T has no virtual base classes
    Текст был переведён автоматически через Google Translate.
    Вы можете проверить и исправить перевод. Для инструкций кликните сюда.
  • Этот шаг конструктора выбран для каждого прямого базы T тривиально
    Оригинал:
    The move constructor selected for every direct base of T is trivial
    Текст был переведён автоматически через Google Translate.
    Вы можете проверить и исправить перевод. Для инструкций кликните сюда.
  • Этот шаг конструктора выбран для каждого нестатический тип класса (или массив типа класса) Член КЛУБА T тривиально
    Оригинал:
    The move constructor selected for every non-static class type (or array of class type) memeber of T is trivial
    Текст был переведён автоматически через Google Translate.
    Вы можете проверить и исправить перевод. Для инструкций кликните сюда.
Тривиальным конструктором шаг конструктор, который выполняет те же действия, как тривиальный конструктор копирования, который делает копию объекта представления, как по 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 Translate.
Вы можете проверить и исправить перевод. Для инструкций кликните сюда.

[править] Неявно определенный ход конструктора

Если неявно объявлен движение конструктор не удаляется и не тривиально, оно определено (то есть, тела функции создается и компилируется) компилятором. Для 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 Translate.
Вы можете проверить и исправить перевод. Для инструкций кликните сюда.

[править] Notes

Для того, чтобы сильная гарантия исключения возможных, определяемых пользователем конструкторов движение не должно бросать исключения. В самом деле, стандартные контейнеры обычно полагаются на 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 Translate.
Вы можете проверить и исправить перевод. Для инструкций кликните сюда.
Если оба копирования и перемещения конструкторы при условии, разрешение перегрузки выбирает движение конструктор, если аргумент 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 Translate.
Вы можете проверить и исправить перевод. Для инструкций кликните сюда.
Во многих ситуациях, перемещение конструкторы оптимизирована, даже если они будут производить наблюдаемые побочные эффекты, см. Копия элизии
Оригинал:
In many situations, move constructors are optimized out even if they would produce observable side-effects, see Копия элизии
Текст был переведён автоматически через Google Translate.
Вы можете проверить и исправить перевод. Для инструкций кликните сюда.

[править] Пример

#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