表面的には、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
インスタンスのメモリレイアウトは変更されますか?
ありがとうございました。
以来ClassWithFooMember
、このようなA「の」オブジェクトがvector
割り当てられている個別に、あなたfoo_ptr
(またはポインタ全体の ClassWithFooMember
オブジェクトが)にかかわらず、有効なままになります任意の上で操作v
限り(匿名)としてClassWithFooMember
オブジェクトが存在します。たとえば、並べ替えv
や再割り当ては無害です。v.erase(v.begin())
もちろん、それを破壊するでしょうが、それでもあなたは最初にどちらかを書いたかもしれません
auto p=std::move(v.front());
auto *q=v.front().release();
これは、完全に破壊 した後、オブジェクトを存続させますv
。
これはすべて、コンテナの種類に関係なく当てはまります。これは、個別の割り当てに使用される追加のメモリと時間のオーバーヘッドによって支払われる利点です。どちらも特定のものではありませんstd::unique_ptr
(ただし、他の理由から、ここでは一般的に適切な選択です)。要素自体を参照する(または)ではなく、(またはへのポインタ)std::vector<T*>
を保持しても安全であることを含め、同じ動作をします。(あなたの場合の対応する危険なことは、またはを保持することですが、これは通常、とにかく行うべきではありません。)T*
T
T*&
T**
vector
std::unique_ptr<ClassWithFooMember>&
std::unique_ptr<ClassWithFooMember>*
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加