将元素插入容器:复制构造函数会混乱指针

时间:2016-12-25 23:31:14

标签: c++ c++11 containers copy-constructor

我的问题是默认复制constr。搞砸了我的指示。

简化版:

  • 我有一个A类,其中包含默认副本constr。

  • A有2个成员对象:BC

  • B指向C

情况:

  • 我将A存储在std::vectorvector.emplace_back(A(...));

  • emplace_back这样做:

    • 创建 A(设置 B指向C 的指针等)

    • A复制到矢量中。 (默认复制ctr:按复制)

    • 销毁"来源"甲

。  的结果:

  • 存储空间中有一个A,其B指针指向 A的C.它不再存在。

简单的解决方案是:

  • A中会有指向BC
  • 的指针

但这并不是那么好,因为A为什么要有指针,当它拥有B和C以及B和C与A共存时。

问题:

  • 有没有比在A中指针更好的方法?

  • 或者是不是比复制构造函数实现更简单?

  • 我认为安抚构建"就地",为什么它需要复制ctr?

2 个答案:

答案 0 :(得分:1)

  

有没有比在A中指针更好的方法?

是的,有。此外,我还没有看到A中的指针如何解决问题。

解决方案是为A编写用户定义的复制构造函数,它将更新复制成员的指针。

  

或者还没有比复制构造函数实现更简单的方法吗?

不,复制构造函数(可能可以说是?)是更新成员成员指针的最简单方法。

  

我认为安抚构建"就地"

确实如此。

  

那为什么需要复制ctr?

一般情况并非如此。

在这种情况下,它确实需要移动或复制构造函数,因为您传递了一个临时对象。向量中的对象是通过使用移动(或复制,如果不是可移动的)构造函数和临时作为参数来构造的。#34;

相反,您可以将A direclty的构造函数的参数传递给emplace_back,这样就不会涉及临时性。

请注意,就地构造对象并不会阻止向量元素被复制,除非您预先保留了内存以便不会重新分配。

答案 1 :(得分:0)

您可以手动编写A的复制构造函数来做正确的事。

如果一切都是标准布局,另一个计划是使用偏移指针。偏移指针存储指针本身与其指向的地址之间的差异。它通常使用max(ptrdiff_t)作为null。

如果仔细写,这些允许子结构之间的指针是默认可复制的,因为两者的相对地址在复制后保持不变。

然而,可能更好的计划是扩充B中的所有方法以获取指向C的指针,并在每次传递它而不是存储冗余状态。

从上面确定正确答案的很多内容与A BC的含义有关,以及它们真正的独立性。