Конструктор без шаблона для класса X является ,copy constructor если ее первый параметр имеет тип X&, const X&, volatile X& или const volatile X&, и либо нет других параметров или также все другие параметры default arguments. [ Example: X::X(const X&) и X::X(X&,int=1) являются конструкторами копирования.
struct X { X(int); X(const X&, int = 1); }; X a(1); // calls X(int); X b(a, 0); // calls X(const X&, int); X c = b; // calls X(const X&, int);
— end example ]
Конструктор без шаблона для класса X является , move constructor если ее первый параметр имеет тип X&&, const X&&, volatile X&&или const volatile X&&, и либо нет других параметров или также все другие параметры default arguments. [ Example: Y::Y(Y&&) - конструктор перемещения.
struct Y { Y(const Y&); Y(Y&&); }; extern Y f(int); Y d(f(1)); // calls Y(Y&&) Y e = d; // calls Y(const Y&)
— end example ]
[ Note: Все формы конструктора копирования / перемещения могут быть объявлены для класса. [ Example:
struct X { X(const X&); X(X&); // OK X(X&&); X(const X&&); // OK, but possibly not sensible };
— end example ] ] — end note
[ Note: Если класс X имеет только конструктор копирования с параметром типа X&, инициализатор типа const X или volatile X не может инициализировать объект типа (возможно, с квалификацией cv) X. [ Example:
struct X { X(); // default constructor X(X&); // copy constructor with a non-const parameter }; const X cx; X x = cx; // error: X::X(X&) cannot copy cx into x
— end example ] ] — end note
Объявление конструктора для класса X неправильно сформировано, если его первый параметр имеет тип (необязательно cv-квалифицированный) X и либо нет других параметров, либо все другие параметры имеют аргументы по умолчанию. Шаблон функции-члена никогда не создается для создания такой сигнатуры конструктора. [ Example:
struct S { template<typename T> S(T); S(); }; S g; void h() { S a(g); // does not instantiate the member template to produce S::S<S>(S); // uses the implicitly declared copy constructor }
— end example ]
Если в определении класса явно не объявляется конструктор копирования, объявляется неявный конструктор implicitly. Если в определении класса объявляется конструктор перемещения или оператор присваивания перемещения, неявно объявленный конструктор копирования определяется как удаленный; в противном случае он определяется как defaulted. Последний случай считается устаревшим, если в классе есть объявленный пользователем оператор присваивания копии или объявленный пользователем деструктор.
Неявно объявленный конструктор копирования для класса X будет иметь форму
X::X(const X&)
если каждый потенциально сконструированный подобъект типа класса M (или его массива) имеет конструктор копирования, первый параметр которого имеет тип const M& или const volatile M&.119 В противном случае неявно объявленный конструктор копии будет иметь вид
X::X(X&)
Если в определении класса X явно не объявляется конструктор перемещения, неявный конструктор будет неявно объявлен как заданный по умолчанию тогда и только тогда, когда
X не имеет объявленного пользователем конструктора копирования,
X не имеет объявленного пользователем оператора присваивания копии,
X не имеет объявленного пользователем оператора присваивания перемещения, и
X не имеет деструктора, объявленного пользователем.
[ Note: Когда конструктор перемещения не объявляется неявно или не предоставляется явно, выражения, которые в противном случае вызвали бы конструктор перемещения, могут вместо этого вызывать конструктор копирования. ] — end note
Неявно объявленный конструктор копирования / перемещения является inline public членом своего класса. Конструктор копирования / перемещения по умолчанию для класса X определяется так, как deleted если бы он X имел:
вариантный член с нетривиальным соответствующим конструктором и X является классом, подобным объединению,
потенциально сконструированный тип подобъекта M (или его массив), который не может быть скопирован / перемещен, поскольку overload resolutionв применении к Mсоответствующему конструктору find приводит к неоднозначности или к функции, которая удаляется или недоступна из конструктора по умолчанию,
любой потенциально сконструированный подобъект типа с деструктором, который удален или недоступен из конструктора по умолчанию, или
для конструктора копирования - нестатический член данных ссылочного типа rvalue.
Конструктор перемещения по умолчанию, который определен как удаленный, игнорируется разрешением перегрузки ([over.match], [over.over]). [ Note: В противном случае удаленный конструктор перемещения помешал бы инициализации из rvalue, который вместо этого может использовать конструктор копирования. ] — end note
Конструктор копирования / перемещения для класса X является тривиальным, если он не предоставляется пользователем и если:
класс X не имеет virtual functions и нет virtual base classes, и
конструктор, выбранный для копирования / перемещения каждого прямого подобъекта базового класса, является тривиальным, и
для каждого нестатического члена данных, X который относится к типу класса (или его массиву), конструктор, выбранный для копирования / перемещения этого члена, является тривиальным;
в противном случае - конструктор копирования / перемещения non-trivial.
Конструктор копирования / перемещения, который установлен по умолчанию и не определен как удаленный, - implicitly defined это если он есть odr-used или когда он явно задан по умолчанию после его первого объявления. [ Note: Конструктор копирования / перемещения определяется неявно, даже если реализация опускает его odr-use ([class.temporary]). ] Если неявно определенный конструктор удовлетворяет требованиям a , то неявно определенный конструктор будет . — end note constexpr constructor constexpr
Прежде чем конструктор копирования / перемещения по умолчанию для класса будет неявно определен, все не предоставленные пользователем конструкторы копирования / перемещения для его потенциально созданных подобъектов должны быть неявно определены. [ Note: Неявно объявленный конструктор копирования / перемещения имеет подразумеваемый exception specification. ] — end note
Неявно определенный конструктор копирования / перемещения для класса, неX являющегося объединением, выполняет поэлементное копирование / перемещение его баз и членов. [ Note: Инициализаторы нестатических элементов данных по умолчанию игнорируются. См. Также пример в [class.base.init]. ] Порядок инициализации такой же, как порядок инициализации баз и членов в определяемом пользователем конструкторе (см. ). Пусть будет либо параметром конструктора, либо, для конструктора перемещения, значением xvalue, относящимся к параметру. Каждый базовый или нестатический член данных копируется / перемещается в соответствии с его типом: — end note [class.base.init] x
если член является массивом, каждый элемент напрямую инициализируется соответствующим подобъектом x;
если член m имеет ссылочный тип rvalue T&&, он инициализируется напрямую с помощью static_cast<T&&>(x.m);
в противном случае база или член инициализируются напрямую соответствующей базой или членом x.
Подобъекты виртуального базового класса должны быть инициализированы только один раз неявно определенным конструктором копирования / перемещения (см [class.base.init]. Раздел "Ресурсы" ).
Неявно определенный конструктор копирования / перемещения для союзной X копирует object representation из X.
Это означает, что ссылочный параметр неявно объявленного конструктора копирования не может связываться с volatile lvalue; см [diff.special].