将元素插入容器:复制构造函数弄乱了指针
Inserting element to container: copy constructor messes up pointers
我的问题是 默认复制构造。弄乱了我的指针。
简化版:
我有一个 A
class 和 default 复制结构
A
有 2 个成员对象:B
和 C
。
B
有指向 C
.
的指针
情况:
我将 A
存储在 std::vector
中:vector.emplace_back(A(...));
emplace_back 这样做:
正在创建 A(设置B指向C的指针等)
复制 A 到向量中。 (默认复制点击率:按值复制)
毁灭 "origin" A.
。
结果:
- 存储有一个
A
,它有一个 B
,它有一个指向 old A 的 C 的指针。它不再存在了。
简单的解决方案是:
- 在
A
中会有指向B
和C
的指针
但这不是很好,因为当 A 拥有它的 B 和 C 并且 B 和 C 与 A 共享生命周期时,为什么 A 应该有指针。
问题:
有没有比在 A 中使用指针更好的方法?
或者有没有比搞乱复制构造函数实现更简单的方法?
我还以为emplace构造的是"in-place",为什么还需要copy ctr?
Isn't there a better way than having pointers in A?
是的,有。此外,我看不出 A
中的指针如何解决问题。
一个解决方案是为 A
编写一个用户定义的复制构造函数,它将更新复制成员的指针。
Or isn't there a simplier way than messing with copy constructor implementations?
不,复制构造函数是(也许可以说?)更新成员的成员指针的最简单方法。
I thought that emplace constructs "in-place"
确实如此。
so why does it need a copy ctr?
一般不会。
在这种情况下,它确实需要移动或复制构造函数,因为您向它传递了一个临时对象。向量中的对象是 "in-place" 构造的,方法是使用移动(或复制,如果不可移动)构造函数,并将临时对象作为参数。
相反,您可以将 A
的构造函数的参数直接传递给 emplace_back
,这样就不会涉及临时变量。
请注意,就地构建对象不会阻止向量元素被复制,除非您已预先保留内存以便不会发生重新分配。
你可以手动编写A
的复制构造函数来做正确的事情。
如果一切都是标准布局,另一个计划是使用偏移指针。偏移指针存储指针本身与其指向的地址之间的地址差异。它通常使用 max(ptrdiff_t) 作为 null.
如果仔细编写,这些允许子结构之间的指针默认可复制,因为两者的相对地址在复制后保持不变。
但是,可能更好的计划是增加 B
中的所有方法以获取指向 C 的指针,并每次都将其传递而不是存储冗余状态。
决定上述正确答案的很多因素都与 A
B
和 C
的含义以及它们真正的独立性有关。
我的问题是 默认复制构造。弄乱了我的指针。
简化版:
我有一个
A
class 和 default 复制结构A
有 2 个成员对象:B
和C
。B
有指向C
. 的指针
情况:
我将
A
存储在std::vector
中:vector.emplace_back(A(...));
emplace_back 这样做:
正在创建 A(设置B指向C的指针等)
复制 A 到向量中。 (默认复制点击率:按值复制)
毁灭 "origin" A.
。 结果:
- 存储有一个
A
,它有一个B
,它有一个指向 old A 的 C 的指针。它不再存在了。
简单的解决方案是:
- 在
A
中会有指向B
和C
的指针
但这不是很好,因为当 A 拥有它的 B 和 C 并且 B 和 C 与 A 共享生命周期时,为什么 A 应该有指针。
问题:
有没有比在 A 中使用指针更好的方法?
或者有没有比搞乱复制构造函数实现更简单的方法?
我还以为emplace构造的是"in-place",为什么还需要copy ctr?
Isn't there a better way than having pointers in A?
是的,有。此外,我看不出 A
中的指针如何解决问题。
一个解决方案是为 A
编写一个用户定义的复制构造函数,它将更新复制成员的指针。
Or isn't there a simplier way than messing with copy constructor implementations?
不,复制构造函数是(也许可以说?)更新成员的成员指针的最简单方法。
I thought that emplace constructs "in-place"
确实如此。
so why does it need a copy ctr?
一般不会。
在这种情况下,它确实需要移动或复制构造函数,因为您向它传递了一个临时对象。向量中的对象是 "in-place" 构造的,方法是使用移动(或复制,如果不可移动)构造函数,并将临时对象作为参数。
相反,您可以将 A
的构造函数的参数直接传递给 emplace_back
,这样就不会涉及临时变量。
请注意,就地构建对象不会阻止向量元素被复制,除非您已预先保留内存以便不会发生重新分配。
你可以手动编写A
的复制构造函数来做正确的事情。
如果一切都是标准布局,另一个计划是使用偏移指针。偏移指针存储指针本身与其指向的地址之间的地址差异。它通常使用 max(ptrdiff_t) 作为 null.
如果仔细编写,这些允许子结构之间的指针默认可复制,因为两者的相对地址在复制后保持不变。
但是,可能更好的计划是增加 B
中的所有方法以获取指向 C 的指针,并每次都将其传递而不是存储冗余状态。
决定上述正确答案的很多因素都与 A
B
和 C
的含义以及它们真正的独立性有关。