提问者:小点点

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


从表面上看,我喜欢使用unique_ptr的容器来拥有数据的模式。 我的问题是,如果我知道unique_ptr不会超出范围,那么获取指向这样一个拥有对象成员的指针/引用是否安全?

例如,我可能

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

然后我能安全地做吗

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

如果我知道v将比foo_ptr活得久,并且v永远不会删除某个项?

如果向v添加了许多项,或者v的内部表示形式发生了变化,会发生什么? ClassWithFoomember实例的内存布局是否会改变?

谢谢。


共1个答案

匿名用户

由于这样的向量中的类WithFoomember对象是单独分配的,因此只要存在(匿名的)类WithFoomember对象,您的foo_ptr(或指向整个类WithFoomember对象的指针)无论对v的任何操作都将保持有效。 例如,对V进行排序或使其重新分配将是无害的。 当然,v.erase(v.begin())会破坏它,但即使这样,您也可能首先编写了

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

这将使对象在完全破坏v之后继续生存。

无论容器类型如何,所有这些都是正确的; 这是由用于单独分配的额外内存和时间开销所支付的好处。 它也不特定于std::unique_ptr(尽管出于其他原因,这里通常是一个不错的选择); std::vector将具有相同的行为,包括保留一个t*(或指向t的指针)而不是引用vector元素本身的t*(或t**)将是安全的。 (在您的情况下,相应的不安全做法是保存std::unique_ptr&std::unique_ptr*,通常不应该这样做。)