简体   繁体   English

我认为数组是不可复制的

[英]I thought array was non copyable

I was under the impression that array were non copyable (or assignable). 我的印象是阵列是不可复制的(或可分配的)。

int x[5] = {1,2,3,4,5};
int y[5] = {6,7,8,9,0};

x = y; // Fails to compile

But when I put an array inside a class the copy constructor and assignment operator work (I would say as expected but its not what I expected). 但是当我在一个类中放入一个数组时,复制构造函数和赋值运算符工作(我会按预期说,但它不是我所期望的)。

#include <iostream>

struct X
{
    virtual ~X(){} // Just in case it was something to do with POD 
                   // make sure its not a POD
    int x[5];
};

int main()
{
    X   a;

    a.x[0]  = 0;
    a.x[1]  = 1;
    a.x[2]  = 2;
    a.x[3]  = 3;
    a.x[4]  = 4;

    // Make a copy of a and test it
    X   b(a);          
    std::cout << a.x[0] << " : " << b.x[0] << "\n";

    b.x[0]  = 10;
    b.x[1]  = 11;
    b.x[2]  = 12;
    b.x[3]  = 13;
    b.x[4]  = 14;

    // Now that we have modified 'b' make sure it is unique.
    std::cout << a.x[0] << " : " << b.x[0] << "\n";

    // Use assignment and see if it worked.
    b   = a;
    std::cout << a.x[0] << " : " << b.x[0] << "\n";
}

Compile and Run 编译并运行

> g++ t.cpp
> ./a.out
0 : 0
0 : 10
0 : 0

What is going on here? 这里发生了什么?

The defaulted copy constructor and assignment operator use copy construction and assignment individually on each member. 默认的复制构造函数和赋值运算符分别对每个成员使用复制构造和赋值。 When there's an array, copy construction or assignment is used on each element of the array (which is quite well-defined). 当有数组时,在数组的每个元素上使用复制构造或赋值(这是非常明确的)。

Here's the rule, from section 12.8 ( [class.copy] ): 这是规则,从第12.8节( [class.copy] ):

The implicitly-defined copy/move constructor for a non-union class X performs a memberwise copy/move of its bases and members. 非联合类X的隐式定义的复制/移动构造函数执行其基础和成员的成员复制/移动。 [ Note: brace-or-equal-initializers of non-static data members are ignored. [注意:忽略非静态数据成员的大括号或大小写。 See also the example in 12.6.2. 另请参见12.6.2中的示例。 — end note ] The order of initialization is the same as the order of initialization of bases and members in a user-defined constructor (see 12.6.2). - 结束注释]初始化的顺序与用户定义的构造函数中基数和成员的初始化顺序相同(见12.6.2)。 Let x be either the parameter of the constructor or, for the move constructor, an xvalue referring to the parameter. x是构造函数的参数,或者对于移动构造函数, x是引用参数的xvalue。 Each base or non-static data member is copied/moved in the manner appropriate to its type: 以适合其类型的方式复制/移动每个基本或非静态数据成员:

  • if the member is an array, each element is direct-initialized with the corresponding subobject of x ; 如果成员是一个数组,则使用x的相应子对象直接初始化每个元素 ;
  • if a member m has rvalue reference type T&& , it is direct-initialized with static_cast<T&&>(xm) ; 如果成员m具有右值引用类型T&& ,则使用static_cast<T&&>(xm)直接初始化;
  • otherwise, the base or member is direct-initialized with the corresponding base or member of x . 否则,用x的相应基数或成员直接初始化基数或成员。

and

The implicitly-defined copy/move assignment operator for a non-union class X performs memberwise copy/move assignment of its subobjects. 非联合类X的隐式定义的复制/移动赋值运算符执行其子对象的成员复制/移动分配。 The direct base classes of X are assigned first, in the order of their declaration in the base-specifier-list , and then the immediate non-static data members of X are assigned, in the order in which they were declared in the class definition. 首先按照它们在base-specifier-list中的声明顺序分配X的直接基类,然后按照它们在类定义中声明的顺序分配X的直接非静态数据成员。 。 Let x be either the parameter of the function or, for the move operator, an xvalue referring to the parameter. x是函数的参数,或者对于move运算符,是指参数的xvalue。 Each subobject is assigned in the manner appropriate to its type: 每个子对象都以适合其类型的方式分配:

  • if the subobject is of class type, as if by a call to operator= with the subobject as the object expression and the corresponding subobject of x as a single function argument (as if by explicit qualification; that is, ignoring any possible virtual overriding functions in more derived classes); 如果子对象是类类型,就好像通过调用operator =将子对象作为对象表达式而x的对应子对象作为单个函数参数(就像通过显式限定;即忽略任何可能的虚拟覆盖函数在更多派生类中);
  • if the subobject is an array, each element is assigned, in the manner appropriate to the element type ; 如果子对象是一个数组,则以适合于元素类型的方式分配每个元素 ;
  • if the subobject is of scalar type, the built-in assignment operator is used. 如果子对象是标量类型,则使用内置赋值运算符。

The rule for signature selection between C::C(const C&) vs C::C(C&) et al also includes language referring to the array element type. C::C(const C&)C::C(C&)等之间的签名选择规则还包括引用数组元素类型的语言。

Arrays are neither copyable nor assignable. 数组既不可复制也不可赋值。 However, structure with array members have generated copy construction and copy assignment. 但是,具有数组成员的结构已生成复制构造和复制分配。 This is a special rule: ie they don't need to be copyable or assignable themselves. 这是一项特殊规则:即它们本身不需要是可复制的或可分配的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM