【问题标题】:Calling assignment operator on an array在数组上调用赋值运算符
【发布时间】:2016-04-02 04:40:06
【问题描述】:

我想知道这段代码是如何工作的:

struct my_array
{
    int r[1000];
};

int main()
{
    my_array foo, bar;
    foo = bar;
}

因为foo = bar 调用将为类调用构造函数提供的operator=,这将懒惰地将其应用于每个成员。但是数组没有operator= 的实现,证明是,这段代码编译失败:

int main()
{
    int a[1000], b[1000];
    a = b;
}

那么我的第一个代码是怎么编译的呢?

【问题讨论】:

  • 因为structs 和classes 一样,有一个默认的operator= 复制每个成员。
  • @DavidSchwartz 是吗?这就是我写的,默认的operator= 被调用,这反过来将operator= 应用于每个成员,我的问题是:如果数组没有operator=(即无法复制),这将如何工作)
  • 默认operator=复制每个成员。它不一定要对它们调用operator=,除非这是复制它们的适当方式。为什么 structint r[2];struct int r1, r2; 的复制方式不同?
  • @DavidSchwartz:我明白了,感谢您的澄清!

标签: c++ arrays assignment-operator


【解决方案1】:

那么我的第一个代码是怎么编译的呢?

语言规范说它必须工作,编译器实现了该行为。

默认赋值语义在 § 12.8 [class.copy] 的第 28 条中指定。具体来说,对象的数据成员是一一分配的。在数组的情况下,这个数组的元素被一一分配。

隐式定义的复制/移动赋值运算符 非联合类 X 执行其成员的复制/移动分配 子对象。 ...

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

(强调我的)


请注意,在您的特定示例中,第一个代码示例调用 未定义的行为,因为在您从此处读取 bar 的元素时未初始化:

foo = bar; // UB: bar.r uninitialized

你可以通过适当的初始化bar来解决这个问题:

my_array foo;
my_array bar{};

【讨论】:

  • 所以标准规定了“复制”数组的含义。我猜operator= 没有为数组定义的唯一原因是当数组衰减为指针时会造成混乱?
  • @qdii 这是从 C 继承来的一团糟。尽管我没有看到分配明显的问题,但很难协调数组副本与指针衰减(尤其是数组函数参数调整)。但它就是这样,无法改变。
猜你喜欢
  • 1970-01-01
  • 2020-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-06
  • 1970-01-01
  • 2014-04-18
  • 1970-01-01
相关资源
最近更新 更多