首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

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)

?

解释

  1. 副本构造函数的典型声明。
  1. 强制编译器生成副本构造函数。
  1. 避免复制构造函数的隐式生成。

每当一个对象被调用时,都会调用复制构造函数。初始化28%直接初始化或复制初始化%29来自同一类型的另一个对象%28,除非过载分辨率选择更好的匹配,否则调用是利兹%29,其中包括。

  • 初始化:T a = b;T a(b);,其中b是类型的T
  • 函数参数传递:f(a);,在哪里a是类型的Tfvoid f(T t)
  • 函数返回:return a;在诸如T f(),在哪里a是类型的T,它没有移动构造函数。

隐式声明复制构造函数

如果没有为类类型%28提供用户定义的副本构造函数struct,,,class,或union%29,编译器将始终将副本构造函数声明为非-显式inline public它的阶级成员。此隐式声明的复制构造函数具有以下形式:T::T(const T&)如果以下所有内容都是正确的:

  • 每个直接和虚拟基地BT具有一个复制构造函数,其参数为Bconst B&const volatile B&
  • 每个非静态数据成员MT类类型或类类型数组的副本构造函数,其参数为Mconst 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::memmove29%。对于非工会类类型%28classstruct%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)

注记

在许多情况下,复制构造函数是优化的,即使它们会产生明显的副作用,请参阅复制省略...

二次

代码语言:javascript
复制
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

代码语言:txt
复制
 ? cppreference.com

在CreativeCommonsAttribution下授权-ShareAlike未移植许可v3.0。

扫码关注腾讯云开发者

领取腾讯云代金券

http://www.vxiaotou.com