2016-03-27 1 views
2

私は、Baseクラス "SceneObject"から派生したオブジェクトを保持するベクトルを保持しています。ここに見られるように、この作業のために、私は、私はユニークなポインタを使用していたことがわかった:派生クラスを保持するベクトルからオブジェクトに変数を初期化する

vector<std::unique_ptr<SceneObject>> objects; 

このベクトル内の私のオブジェクトを配置するには、私は新しいキーワードとヒープ上にメモリを割り当てる:

objects.emplace_back(new Sphere(glm::vec3(0.9, -1.925, -6.69), 0.825, sphereMaterial)); 

は、私のようなループ内でこれらのオブジェクトからの機能にアクセス:

objects[k]->intersect(...); 

しかし、私の問題は、私は、変数「シーンオブジェクト」コンタます初期化したいということですこのベクタに格納されているオブジェクトの1つで、後でいくつかのチェックを行います...ポインタを代わりに格納しようとしていますが、これを行うときにコンパイラエラーが発生しています:

SceneObject* object = NULL; 
for(...) 
    object = &objects[k]; 

エラー:

boilerplate.cpp: In function 'int main(int, char**)': 
boilerplate.cpp:606:15: error: cannot convert '__gnu_cxx::__alloc_traits<std::allocator<std::unique_ptr<SceneObject> > >::value_type* {aka std::unique_ptr<SceneObject>*}' to 'SceneObject*' in assignment 
    object = &objects[k]; 
     ^

私のベース/派生クラスを作成するための​​に見られるように、私はこの方法を使用していました。

この変数を自分のオブジェクトでどのように初期化するべきかに関する提案はありますか?

+0

なぜ 'std :: shared_ptr'を使わないのですか? – wally

答えて

2

あなたが内部に保存されto "unwrap" the raw pointerstd::unique_ptrgetを呼び出す必要があります:あなたはAPIを所有するときの状況でポインタをアンラップ避けることができ

SceneObject* object = NULL; 
for(...) 
    object = objects[k].get(); 

注:std::unique_ptrは、あなたがいるかのように扱うできるように、オペレータ逆参照を提供彼らは実際の指針でした。

2

実際にはunique_ptrが何であるかを覚えておいてください:ポインタを管理し、1つのインスタンスが特定のオブジェクトを指し示すことだけを許可するオブジェクトです。

あなたのベクトルの要素はunique_ptrです。つまり、objects[k]を実行すると、unique_ptrオブジェクトが返されます。 !あなたはここにunique_ptr*SceneObject*ポインタを初期化しようとしている。

SceneObject* object = NULL; object = &objects[k];

しかし、明らかにSceneObject*を= unique_ptr*スマートポインタの目標は、あなたが使用しているので、もし、生のポインタを使用しないことです

unique_ptrがベクター内にあり、ベクター要素が破壊された状態で問題ない場合は、unique_ptr<SceneObject> object;もループに使用する必要があります。そして、それだけだ。

for(...) object = objects[k];

あなたがそれらをベクトルで有効なままにしたい場合は、両方の場所でshared_ptr年代を使用する必要があります。