简体   繁体   English

当 unique_ptr 在向量中时,对 std::unique_ptr<> owned object 的引用/ptr 是否安全?

[英]Is having a reference/ptr to std::unique_ptr<> owned object safe when the unique_ptr is in a vector?

On the surface I like the pattern of having a container of unique_ptr 's to own data.从表面上看,我喜欢使用unique_ptr的容器来拥有数据的模式。 My question is, is it safe to then take pointers/references to members of such an owned object, if I know that the unique_ptr will not go out of scope?我的问题是,如果我知道unique_ptr不会从 scope 中获取 go,那么对这样一个拥有的 object 的成员进行指针/引用是否安全?

For example I may have例如我可能有

auto v = std::vector<std::unique_ptr<ClassWithFooMember>>{};
v.emplace_back(std::make_unique<ClassWithFooMember>());

Can I then safely do我可以安全地做吗

auto *foo_ptr = &(v.at(0)->foo);

if I know that v will outlive foo_ptr and that v will never have an item removed?如果我知道v将比foo_ptr并且v永远不会删除任何项目?

What happens if many items are added to v or if v 's internal representation changes?如果向v添加了很多项或者如果v的内部表示发生了变化,会发生什么情况? Will the memory layouts of the ClassWithFooMember instances ever change? ClassWithFooMember实例的 memory 布局会改变吗?

Thank you.谢谢你。

Since the ClassWithFooMember objects “in” such a vector are allocated separately , your foo_ptr (or a pointer to the entire ClassWithFooMember object) will remain valid regardless of any operations on v so long as the (anonymous) ClassWithFooMember object exists.由于“在”此类vector中的ClassWithFooMember对象是单独分配的,因此只要(匿名) ClassWithFooMember object 存在,无论对v进行任何操作,您的foo_ptr (或指向整个ClassWithFooMember对象的指针)都将保持有效。 For instance, sorting v or causing it to reallocate would be harmless.例如,对v进行排序或使其重新分配是无害的。 v.erase(v.begin()) would destroy it, of course, but even then you might first have written either of v.erase(v.begin())当然会破坏它,但即使那样你也可能先写了

auto p=std::move(v.front());
auto *q=v.front().release();

which would let the object live on after destroying v entirely.这将使 object 在完全销毁v后继续存在。

All this is true regardless of the container type ;无论容器类型如何,这一切都是正确的; this is the benefit paid for by the additional memory and time overhead used for the separate allocation.这是额外的 memory 和用于单独分配的时间开销所支付的收益。 Neither is it specific to std::unique_ptr (although that's generally a good choice here for other reasons);它也不是特定于std::unique_ptr的(尽管出于其他原因,这通常是一个不错的选择); std::vector<T*> would have the same behavior, including that it would be safe to retain a T* (or a pointer into a T ) but not a T*& (or T** ) referring to the vector element itself . std::vector<T*>将具有相同的行为,包括保留T* (或指向T的指针)而不是引用vector元素的T*& (或T** )是安全的本身 (The corresponding unsafe thing in your case would be to hold a std::unique_ptr<ClassWithFooMember>& or std::unique_ptr<ClassWithFooMember>* , which you generally shouldn't be doing anyway.) (在你的情况下相应的不安全的事情是持有一个std::unique_ptr<ClassWithFooMember>&std::unique_ptr<ClassWithFooMember>* ,你通常不应该这样做。)

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

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