从表面上看,我喜欢使用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
实例的内存布局是否会改变?
谢谢。
由于这样的向量
中的类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
,通常不应该这样做。)