2016-08-03 2 views
0

Если я хочу сделать-структуру для представления элемента для визуализации на экране, и содержит:C++: Нулевые указатели и структуры

  1. Список уроженцев «renderables» (meshes, triangles и т.д.)
  2. указатель на другие подструктуры

ли это:

struct RenderGroup { 
    std::vector<RenderGroup*> Children; 
    std::vector<Renderable> Renderables; 
} 

Каков наилучший способ сделать это? И если у меня нет подструктур, могу ли я просто поместить нулевой указатель в вектор?

Редактировать: Плохих теги

+5

Если у вас нет подструктур, не помещайте * ничего * в вектор. – Galik

+0

Если вам нужно спросить, подходит ли нулевой указатель на вашем графике, тогда у вас будет плохое время. –

ответ

1

std::vector не фиксированный размер, поэтому, если нет элементов в нем, size вернется 0 и пустой вернется true.

std::vector<int> v; 
auto sz = v.size(); // sz has value 0 
auto e = v.empty(); // true 
v.push_back(42); 
sz = v.size(); // 1 
e = v.emi empty(); // false 

Вы также можете удалить элементы (вектор перемещает все элементы followingv вниз, чтобы заполнить пробел)

std::vector<int> v { 1, 2, 3 }; 
auto it = v.find(2); 
if (it != v.end()) 
    v.erase(it); // v now contains 1, 3 

Таким образом, в теории, ни вам не нужно ставить nullptr в твоих вектор. Это предполагает, что вы разработали свое приложение таким образом, чтобы не требовался определенный размер популяции в вашем векторе; если это так, то вектор не может быть правильным контейнером. Рассмотрим std :: array.

Существует проблема с вашим вектором рендеринга: векторные магазины экземпляры из Renderable. Элементы I являются вектором точно размера Renderable. Поэтому, если вы попытаетесь сохранить производный класс, например Mesh, вы потеряете дополнительные поля производных классов.

Это называется нарезкой.https://en.m.wikipedia.org/wiki/Object_slicing

Вам нужно будет хранить указатели или ссылки на экземпляры объектов. Это зависит от продолжительности жизни и владения экземплярами.

Если вашему вектору принадлежат исправления, вы можете использовать std::vector<std::unique_pre<Remediable>>.

Если вам даны экземпляры вашего звонящего, возможно, std::shared_ptr.

+0

Спасибо за полезный ответ. Итак, как решить проблемы нарезки? Указатели? – PearlSek

1

Там нет необходимости ставить произвольную «ничего» запись в std::vector, это не как массив C-стиле переменной длиной, где вы должны прекратить с каким-то разделителем , Просто оставьте его пустым.

В обычной практике вы не должны ставить NULL в списки, подобные этому, когда что-то может перебирать содержимое и повторно ссылаться на этот указатель, вызывая сбой.

+3

Избегайте 'NULL' тоже. Используйте 'nullptr'. –

+0

'nullptr' не определен в некоторых более старых версиях C++. –

+0

@MarkLakata Хорошая точка, но независимо от того, как вы ее указываете, '0' или иначе, недопустимые указатели не должны быть в этом списке. – tadman

0

Если RenderGroup базовый класс и ваш Children вектор хранения произвольных детей классов RenderGroup этот подход «отлично» (хотя умные указатели, вероятно, было бы предпочтительнее).

Однако, как сказал тадман, если вы используете указатели для представления отсутствия RenderGroup, вы, вероятно, захотите вместо этого просто удалить элементы в векторе, когда они больше не нужны.

0

Смотрите, если эта структура может помочь:

struct RenderGroup { 
    std::map<Renderable, std::vector<RenderGroup*>> Renderables; 
} 

Список ребенка (RenderGroup) объекты отображаются на визуализируемый объект.