【问题标题】:Indirect array assignment works, while direct array assignment does not [duplicate]间接数组赋值有效,而直接数组赋值不起作用
【发布时间】:2015-03-21 10:17:22
【问题描述】:

两种数组赋值有什么区别,一种在结构内,一种在结构外?

struct A
{
   char s[4];
};

int main(int argc, char *argv[])
{
   char s[4];
   char d[4];

   d = s; // 'invalid array assignment'

   A a, b;
   b = a; // compiles without problems

   return 0;
}

默认运算符= 应该调用逐个成员的赋值运算符。如果是这样,那么应该存在一个数组赋值运算符,但编译器不想显式调用它。为什么?

【问题讨论】:

  • 您的“间接数组赋值”是一种结构赋值,通常用于从函数返回固定数组并将所述结构作为值参数传递。 a.s = b.s 显然同样会失败。
  • 因为 C++ 有其疯狂的一面——这里的疯狂之处在于数组不是该语言的一等公民(例如,它们不可复制并且通常衰减为指针),因此结构复制必须具有一个特殊的规则,它说数组成员是按元素复制的。如果不是这样,而数组和其他类型一样,结构复制规则只会说“所有成员都被复制”。

标签: c++ arrays variable-assignment


【解决方案1】:

数组名(例如s)的值是数组的起始地址。一旦数组在内存中分配,该地址应该是固定的。 d = s是说将s[4]的起始地址分配给d[4],显然做不到。

像你这样的简单结构只是一小部分。在您的情况下,A 的实例占用 4 个字节。当您执行a = b 时,它会将b 的位复制到a 的位。

为了说明区别,我认为你不能做到a.s = b.s。你可以试试。

【讨论】:

    【解决方案2】:

    我认为这就是为什么... Struct 是一个类对象,并且有这个特殊的规则来分配成员它的数组,而不是数组本身 (c++14 draft):

    12.8 复制和移动类对象

    12.8.28。非联合类 X 的隐式定义的复制/移动赋值运算符执行成员复制- /move 分配其子对象。首先分配 X 的直接基类,按照它们的顺序 在 base-specifier-list 中声明,然后分配 X 的直接非静态数据成员,在 它们在类定义中的声明顺序。让 x 是函数的参数 或者,对于移动运算符,引用参数的 xvalue。每个子对象的分配方式 适合其类型:

    1. ——如果子对象是一个数组,则以适合元素类型的方式分配每个元素;

    所以复制过程不是为数组定义的(因为它是不可修改的变量类型),而是为数组的成员类型定义的。没有为数组定义隐式operator=。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-08
      • 2011-05-06
      • 1970-01-01
      • 1970-01-01
      • 2021-03-16
      • 1970-01-01
      • 1970-01-01
      • 2019-11-14
      相关资源
      最近更新 更多