2016-03-27 7 views
2

У меня есть вектор, который содержит объекты, которые являются производными классами из базового класса «SceneObject». Для решения этой задачи, я обнаружил, что я должен был использовать уникальные указатели, как показано здесь:Инициализация переменной для объекта из векторных холдинговых производных классов

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

Чтобы поместить свои объекты внутри этого вектора, я выделить память в куче с нового ключевым словом:

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

I доступ к функциям из этих объектов в цикле, как:

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

Но моя проблема в том, что я хочу, чтобы инициализировать переменную «SceneObject», который будет Contà в одном из объектов, хранящихся в этом векторе, для выполнения некоторых проверок позже ... Я пытаюсь сохранить указатель вместо этого, как мне кажется, я должен делать, но при этом получаю ошибку компилятора:

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]; 
     ^

Я использовал этот метод, как показано в this example code для создания своих базовых/производных классов.

Любое предположение относительно того, как я должен инициализировать эту переменную с помощью моего объекта?

+0

Почему бы не использовать 'std :: shared_ptr'? – wally

ответ

2

Вам нужно позвонить get на std::unique_ptrto "unwrap" the raw pointer хранится внутри:

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

Обратите внимание, что вы можете избежать разворачивания указателя в ситуациях, когда у вас есть API: std::unique_ptr предоставляет операторам разыменования, что позволяет рассматривать их как если они были настоящими указателями.

2

Помните, что на самом деле unique_ptr: это объект, который управляет вашим указателем и позволяет одному экземпляру указывать на данный объект.

Итак, элемент вашего вектора - это unique_ptr, что означает, что когда вы делаете objects[k], вы получаете объект unique_ptr. Вы пытаетесь инициализировать SceneObject* указатель на unique_ptr* здесь:

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

Но, очевидно, SceneObject* = unique_ptr*

Цель умных указателей, чтобы избежать использования сырья указатели, так что если вы используете unique_ptr в векторе, и в порядке с разрушаемым векторным элементом, вы должны использовать unique_ptr<SceneObject> object; с вашей петлей. Тогда это просто:

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

Если вы хотите, чтобы они оставались в силе в векторе, вы должны использовать shared_ptr «с в обоих местах.