Copy constructors
复制构造函数
类的副本构造函数T
是一个非模板构造函数,其第一个参数是T&
,,,const T&
,,,volatile T&
,或const volatile T&
,或者没有其他参数,或者其余的参数都有默认值。
句法
class_name ( const class_name & ) | (1) | |
---|---|---|
class_name ( const class_name & ) = default; | (2) | |
class_name ( const class_name & ) = delete; | (3) | |
解释
- 副本构造函数的典型声明。
- 强制编译器生成副本构造函数。
- 避免复制构造函数的隐式生成。
每当一个对象被调用时,都会调用复制构造函数。初始化28%直接初始化或复制初始化%29来自同一类型的另一个对象%28,除非过载分辨率选择更好的匹配,否则调用是利兹%29,其中包括。
- 初始化:
T a = b;
或T a(b,其
中b是类型的T;
- 函数参数传递:
f(a,在
哪里a是类
型的T和f
是v
oid f(T t);
- 函数返回:
return a;
在诸如T f()
,在哪里a
是类型的T
,它没有移动构造函数。
隐式声明复制构造函数
如果没有为类类型%28提供用户定义的副本构造函数struct
,,,class
,或union
%29,编译器将始终将副本构造函数声明为非-显式inline public
它的阶级成员。此隐式声明的复制构造函数具有以下形式:T::T(const T&)
如果以下所有内容都是正确的:
- 每个直接和虚拟基地
B
成T
具有一个复制构造函数,其参数为B
或const B&
或const volatile B&
;
- 每个非静态数据成员
M
成T
类类型或类类型数组的副本构造函数,其参数为M
或const M&
或const volatile M&
...
否则,隐式声明的副本构造函数是T::T(T&)
.%28注意,由于这些规则,隐式声明的复制构造函数不能绑定到易失性lvalue参数。%29。
A class can have multiple copy constructors, e.g. both T::T(const T&) and T::T(T&). If some user-defined copy constructors are present, the user may still force the generation of the implicitly declared copy constructor with the keyword default. | (since C++11) |
---|
隐式声明的%28或其第一次声明的默认%29复制构造函数具有异常规范,如动态异常规范%28直到C++17%29异常规格%28自C++17%29。
隐式删除声明的复制构造函数
The implicitly-declared copy constructor for class T is undefined if any of the following conditions are true: | (until C++11) |
---|---|
The implicitly-declared or defaulted copy constructor for class T is defined as deleted if any of the following conditions are true: | (since C++11) |
T
无法复制%28的非静态数据成员是否已删除、不可访问或模棱两可的复制构造函数%29;
T
具有无法复制%28的直接或虚拟基类已删除、不可访问或模棱两可的复制构造函数%29;
T
具有直接或虚拟基类的已删除或不可访问的析构函数;
T has a user-defined move constructor or move assignment operator; T is a union and has a variant member with non-trivial copy constructor; T has a data member of rvalue reference type. | (since C++11) |
---|
T
具有用户定义的移动构造函数或移动赋值操作符;
T
是一个联合并且有一个具有非平凡复制构造函数的变体成员;
T
具有rvalue引用类型的数据成员。
%28自C++11%29
普通复制构造函数
类的复制构造函数T
如果以下所有内容都为真,则是微不足道的:
- 它不是用户提供的%28,也就是说,它是隐式定义的或默认的%29,如果它是默认的,它的签名与隐式定义的%28相同,直到C++14%29;
T
没有虚拟成员功能;
T
没有虚拟基类;
- 的每个直接基选择的复制构造函数。
T
是微不足道的;
- 的每个非静态类类型%28或类类型%29成员的数组所选择的复制构造函数。
T
是微不足道的;
一个简单的复制构造函数创建参数的对象表示形式的字节级副本,并且不执行其他操作。TriviallyCopyable
对象可以通过手动复制其对象表示来复制,例如std::memmove
所有与C语言%28POD类型%29兼容的数据类型都是可以复制的。
隐式定义的复制构造函数
如果隐式声明的复制构造函数既不删除也不平凡,则定义为%28,即编译器生成和编译函数体%29ODR-使用.为union
类型时,隐式定义的复制构造函数通过以下方式复制对象表示%28std::memmove
29%。对于非工会类类型%28class
和struct
%29,构造函数使用直接初始化,按初始化顺序执行对象%27s基和非静态成员的完整成员级复制。
The generation of the implicitly-defined copy constructor is deprecated if T has a user-defined destructor or user-defined copy assignment operator. | (since C++11) |
---|
注记
在许多情况下,复制构造函数是优化的,即使它们会产生明显的副作用,请参阅复制省略...
例
二次
struct A
{
int n;
A(int n = 1) : n(n) { }
A(const A& a) : n(a.n) { } // user-defined copy ctor
};
struct B : A
{
// implicit default ctor B::B()
// implicit copy ctor B::B(const B&)
};
struct C : B
{
C() : B() { }
private:
C(const C& // non-copyable, C++98 style
};
int main()
{
A a1(7
A a2(a1 // calls the copy ctor
B b;
B b2 = b;
A a3 = b; // conversion to A& and copy ctor
volatile A va(10
// A a4 = va; // compile error
C c;
// C c2 = c; // compile error
}
二次
缺陷报告
以下行为更改缺陷报告追溯应用于先前发布的C++标准。
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
CWG 2171 | C++14 | X(X&) = default was non-trivial | made trivial |
CWG 496 | C++11 | structs with volatile members were trivially copyable | volatile members make copy non-trivial |
CWG 2094 | C++14 | volatile members make copy non-trivial | structs with volatile members are trivially copyable |
© cppreference.com
在CreativeCommonsAttribution下授权-ShareAlike未移植许可v3.0。