forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   C++ (http://forum.boolean.name/forumdisplay.php?f=22)
-   -   контейнеры (http://forum.boolean.name/showthread.php?t=16651)

HolyDel 15.04.2012 15:13

контейнеры
 
часто ли вы храните в контейнерах (std::vector, std::list, std::map, etc) объекты. или же вы чаще храните в них указатели на объекты?

опрос открытый.

mr.DIMAS 15.04.2012 15:30

Ответ: контейнеры
 
Только указатели. Зато нету гемора с конструкторами копирования. Еще удобна связка умных указателей и контейнеров. Это мое ИМХО

HolyDel 15.04.2012 15:45

Ответ: контейнеры
 
Цитата:

Еще удобна связка умных указателей и контейнеров.
особенно auto_ptr :)

у меня очень редко контейнеры содержат сами объекты. С ходу могу вспомнить только глифы. Т.е. когда в контейнере содержится небольшая структурка, типа
Код:

struct Glyph
{
float x,y,dx,dy;
};


Mr_F_ 15.04.2012 16:07

Ответ: контейнеры
 
- зависит от задачи;
- стараюсь избегать std контейнеров;

вообще какой-то странный вопрос.
если я храню указатели на объекты, то где тогда находятся сами объекты?
в рандомное время созданы на куче? такого тоже стараюсь избегать, стоит оптимизировать расположения данных, чтобы помочь кэшу процессора.

HolyDel 15.04.2012 16:35

Ответ: контейнеры
 
Цитата:

- зависит от задачи;
это понятно
Цитата:

- стараюсь избегать std контейнеров;
это не понятно

Цитата:

вообще какой-то странный вопрос.
просто статистика

Цитата:

если я храню указатели на объекты, то где тогда находятся сами объекты?
в рандомное время созданы на куче

SBJoker 15.04.2012 17:48

Ответ: контейнеры
 
В основном указатели, объекты редко, только если небольшие и для удобства менеджмента (очистка списка убивает и объекты)

Mr_F_ 15.04.2012 18:00

Ответ: контейнеры
 
Цитата:

это не понятно
очень плохо себя ведут в мультипоточной обстановке и любят выделять/удалять память когда попало (это и есть главная проблема с мультипоточностью).
например, помню - если сделать вектору reserve, это не гарантирует дальнейшее отсутствие работы с памятью, только при push_back, а если сделать clear, то он все равно вызовет delete по хардкору, и смысл резерва потеряется.
кроме того, очень сложно докапываться до причины бага, когда дебаггер тычет им в недра stl - это кошмарное нагромождение наследований и непонятного кода.
предпочёл написать быдловектор себе по вкусу (задача крайне проста, если не пытаешься угодить всем сразу, а знаешь что тебе нужно) в 1-2 экрана кода, и не парюсь.

mr.DIMAS 15.04.2012 18:30

Ответ: контейнеры
 

Чувствую сейчас опять холивар начнется

impersonalis 15.04.2012 18:33

Ответ: контейнеры
 
Цитата:

Сообщение от SBJoker (Сообщение 225560)
В основном указатели, объекты редко, только если небольшие и для удобства менеджмента (очистка списка убивает и объекты)

так же.
Контейнер подразумевает динамическое изменение своего содержимого. Как правило, это является следствием того, что сущность-владелец контейнера всего-лишь осуществляет менеджмент некоторых объектов:
1) сущность их не создаёт
2) сущность не удаляет их
3) объекты существуют вне сущности
Ну и почему тогда хранить НЕ указатели? Если же концепция другая, т.е. сущность явно агрегирует в себя сами объекты, то как правило (но не всегда) можно обойтись массивом (в т.ч. динамическим).

HolyDel 16.04.2012 00:29

Ответ: контейнеры
 
Mr_F_, а как ты решаешь вопросы многопоточности в своем контейнере. не блокировками же? (мютексами или крит. секциями?)

Mr_F_ 16.04.2012 01:08

Ответ: контейнеры
 
Цитата:

Mr_F_, а как ты решаешь вопросы многопоточности в своем контейнере. не блокировками же? (мютексами или крит. секциями?)
нет, я просто делаю контейнеры, которым обязательно нужно делать reserve перед использованием, после чего они гарантируют отсутствие работы с кучей.
также исключаю insert элемента в абы какое место массива.
дальше остаётся лишь соблюдать правило - 1 поток-писальщик, остальные читальщики.
если нужно менять местами, передвигать элементы массива (не вылезая за его границы), можно иметь дополнительный indirection массив такого же размера, который маппит оригинальные id к новым.

ну это касательно вектора и стринга.
а альтернативу std::map пока не находил и вряд ли напишу удачнее)
так что стараюсь планировать архитектуру так, чтобы им просто не пришлось пользоваться, а если уж никак, то только в одном потоке.

---
+ ещё один камень в огород стл вектора: он не может содержать выравненные данные, типа __declspec(align(16))

impersonalis 29.06.2012 15:07

Ответ: контейнеры
 
Цитата:

Сообщение от impersonalis (Сообщение 225564)
так же.
Контейнер подразумевает динамическое изменение своего содержимого. Как правило, это является следствием того, что сущность-владелец контейнера всего-лишь осуществляет менеджмент некоторых объектов:
1) сущность их не создаёт
2) сущность не удаляет их
3) объекты существуют вне сущности
Ну и почему тогда хранить НЕ указатели? Если же концепция другая, т.е. сущность явно агрегирует в себя сами объекты, то как правило (но не всегда) можно обойтись массивом (в т.ч. динамическим).

И ещё добавлю:
если и в контейнере хранятся не нативные сущности, то организация усложняется сразу. Если с указателями для помещения экземпляра в контейнер достаточно скопировать его адрес (несколько байт), то здесь:
1) нужно перекопировать весь объект;
2) исходный объект удалить (автоматически);
3) если в объекте есть данные, адресуемые указателем (например, динамические массивы), то, вероятно, придётся писать свою реализацию конструктора копирования.
4) конструктор и деструктор (в случае из п.3) тоже придётся реализовать, даже если объект - структура, хранащая пару строк (char*), а их задание и удаление раньше контролировалось вами (до использования контейнера) вручную.

В общем - кроме экономии капли памяти (на указатель) плюсов для использования в контейнерах не указателей, а самих сложных объектов - не вижу.

jimon 29.06.2012 16:46

Ответ: контейнеры
 
немного схоже с Mr_F_, я не использую STL потому что иногда его нет (читай андроид ndk), у меня всего они самодельный контейнер - const array, перед использованием делаем reserve на количество елементов (делает alloc), а дальше аллоцируем из свободных - request (просто смещает индекс свободного элемента и возвращает указатель), удаления нету, если приспичило есть requestMore (делает realloc) но еще ни разу в игровом коде не понадобилось

в плане использования const array - он везде хранит объекты, если приспичило и структуры имеют переменный размер, то я храню тупо массив байт, в будущем сделаю чтобы несколько const array могли юзать внешний кусок данных, чтобы вообще все игровые данные аллочить за один раз (сейчас у меня всё же несколько аллокаций)

поинтеры хранятся только в тех местах где что-то ссылается на что-то (связи в скриптах которые выставляются в редакторе), но тут система чуть хитрее, в данных уровня (те которые из файла копируются в память) резервируется место под поинтер (собсно разный размер под 32\64 бита выходит), но вместо поинтера пишется индекс из нужного массива, после загрузки уровня игра делает link resolve, те проходится по всем классам (у меня свой RTTI, я знаю какой класс какие поинтеры по каким смещениям имеет), и заменяет индексы на актуальные поинтеры

думаю спросите что насчёт деревьев ? любое дерево можно представить линейно в виде массива, и точка

насчёт map ? бинарный поиск наше всё

насчёт динамических структур ? знаете, а они не нужны ! :crazy:

ps. и да, в игре всего ~50 аллокаций и ~30 живых поинтеров, 1 ВБО ! (хотя с ~50 vao), и всего 2-5 текстур, при этом это не хухры мухры, а полноценная игра с кучей мешей, с кучей скелетки (80+ анимаций), с весьма впечатляющим количеством интерфейсов и тд

impersonalis 14.07.2014 15:07

Ответ: контейнеры
 
Vector of Objects vs Vector of Pointers Updated


Часовой пояс GMT +4, время: 21:40.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot