有効な状態でオブジェクトを作成するために、B
これ以上何もする必要はありません。のコンストラクタとデストラクタを宣言して実装する必要もありませんB
。std::vector<std::shared_ptr<A>>
のメンバーは、のコンストラクターでB
デフォルトで初期化されますB
。つまり、コンテナーにはまだ要素がありません。また、デストラクタの~B
おかげで適切に削除されます。std::vector
std::shared_ptr
一方、たとえば何らかの方法で初期化する場合(つまり、3つの値) 、コンストラクター初期化リストでコンストラクターをstd::vector
使用できます。例えば:std::initializer_list
B
class B
{
public:
B(): _innerArray{ std::make_shared<A>(),
std::make_shared<A>(),
std::make_shared<A>() } {}
~B() {}
private:
std::vector<std::shared_ptr<A>> _innerArray;
};
std::make_shared
これは完全な転送を使用するためA
、クラスオブジェクト自体ではなく、関数の引数としてのコンストラクター引数を渡すことに注意してください。
デザインに関する懸念に答えるには、メンバーを共有する前に、まずベクター内のメンバーの独占的所有権について考えることをお勧めします。
class B
{
public:
B();
~B();
private:
std::vector<std::unique_ptr<A>> _innerArray;
};
上記の実装は、多くの理由でより効果的です。まず第一に、それはあなたのデザインを誰がA
sの寿命に責任があるかについてより明確にします。Nextstd::unique_ptr
は、スレッドセーフな参照カウントを必要としないため、より高速です。最後になりましたが、追加のメモリ(通常のCポインタと比較して)は必要ありませんが、std::shared_ptr
共有状態データを格納するのに数十バイト(24〜48)かかる場合があり、小さなクラスで操作する場合は非常に効果がありません。そのため、私は常にstd::unique_ptr
最初の手段としてスマートポインターを使用し、std::shared_ptr
本当に必要な場合にのみフォールバックします。
編集:
あなたの編集に答えて、私はクラスの3つのコンテナを作成しA
ますB
、、C
。事実に応じて、それらをポリモーフィックにする必要があるかどうかに応じて、そのような値(非ポリモーフィックタイプ)を格納します。
std::deque<A> as;
std::deque<B> bs;
std::deque<C> cs;
または(ポリモーフィックタイプ):
std::vector<std::unique_ptr<A>> as;
std::vector<std::unique_ptr<B>> bs;
std::vector<std::unique_ptr<C>> cs;
その順序で(as
より長く生きる必要があり、より長くbs
生きるbs
必要がありcs
ます)。そうすれば、スマートポインターを使用せずに、insideクラスとinsideクラスを作成std::vector<A*>
できB
ますstd::vector<B*>
。C
それがお役に立てば幸いです。
編集:
コンテナ要素への参照/ポインタが。を使用したコンテナ拡張に耐えられるようにする最初のケースでに変更std::vector
されました。ただし、要素の消去、並べ替え、その他のものには耐えられません。std::deque
push_back()