Я должен хранить все объекты или указатели на объекты в контейнерах?

Разработка новой системы с нуля. Я буду использовать STL для хранения списков, и карты определенных да здравствует возражает.

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

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

Два очень очевидных недостатка к проигрыванию с указателями: 1) я должен справиться с выделением/освобождением этих объектов сам в объеме вне STL. 2) я не могу создать временный объект на стеке и добавить его к моим контейнерам.

Есть ли что-либо еще, что я пропускаю?

161
задан Rakete1111 2 July 2017 в 08:20
поделиться

8 ответов

Так как люди вмешиваются на efficency использования указателей.

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

Otoh, если обновления являются общими указателями хранения, сократит затраты копии/перемещения.

67
ответ дан Torbjörn Gyllebring 23 November 2019 в 21:27
поделиться

Это действительно зависит от Вашей ситуации.

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

, Если Вы возражаете, являются большими, и наличие конструктора по умолчанию не имеет смысла, или копии объектов являются дорогими, затем снабжать указателями является, вероятно, способом пойти.

, Если Вы решаете использовать указатели на объекты, смотрите на Библиотека Контейнера Указателя Повышения . Эта библиотека повышения обертывает все контейнеры STL для использования с динамично выделенными объектами.

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

class BigExpensive { ... }

// create a pointer vector
ptr_vector<BigExpensive> bigVector;
bigVector.push_back( new BigExpensive( "Lexus", 57700 ) );
bigVector.push_back( new BigExpensive( "House", 15000000 );

// get a reference to the first element
MyClass& expensiveItem = bigList[0];
expensiveItem.sell();

, Эти классы обертывают контейнеры STL и работают со всеми алгоритмами STL, которые действительно удобны.

существуют также средства для передачи владения указателя в контейнере вызывающей стороне (через функцию выпуска в большинстве контейнеров).

46
ответ дан Nick Haddad 23 November 2019 в 21:27
поделиться

При хранении объектов polymporhic, всегда необходимо использовать набор указателей базового класса.

Это - то, если Вы планируете хранение различных производных типов в Вашем наборе, необходимо сохранить указатели или есться разрезанием deamon.

38
ответ дан philant 23 November 2019 в 21:27
поделиться

Почему бы не получить лучший из обоих миров: сделайте контейнер интеллектуальных указателей (такой как boost::shared_ptr или std::shared_ptr ). Вы не должны управлять памятью, и Вы не должны иметь дело с большими операциями копии.

19
ответ дан Branan 23 November 2019 в 21:27
поделиться

Обычно хранить объекты непосредственно в контейнере STL является лучшим, поскольку это является самым простым, самым эффективным, и является самым легким для использования объекта.

, Если Ваш объект сам имеет non-copyable синтаксис или является абстрактным типом, необходимо будет сохранить указатели (самый легкий, должен использовать shared_ptr)

11
ответ дан Greg Rogers 23 November 2019 в 21:27
поделиться

У Вас, кажется, есть хорошее схватывание различия. Если объекты являются маленькими и легкими скопировать, то любой ценой хранят их.

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

TorbjГ¶rn делает правильное замечание о разрезании.

3
ответ дан Community 23 November 2019 в 21:27
поделиться

Используя указатели будет более эффективным, так как контейнеры будут только копировать указатели вокруг вместо полных объектов.

существует немного полезной информации здесь о контейнерах STL и интеллектуальных указателях:

, Почему он неправильно для использования станд.:: auto_ptr< > со стандартными контейнерами?

3
ответ дан Community 23 November 2019 в 21:27
поделиться

Если объекты состоят в том, чтобы быть упомянуты в другом месте в коде, хранилище в векторе повышения:: shared_ptr. Это гарантирует, что указатели на объект останутся допустимыми при изменении размеров вектора.

Т.е.:

std::vector<boost::shared_ptr<protocol> > protocols;
...
connection c(protocols[0].get()); // pointer to protocol stays valid even if resized

, Если никто еще не хранит указатели на объекты, или список не выращивает и уменьшает, просто хранит как простые объекты:

std::vector<protocol> protocols;
connection c(protocols[0]); // value-semantics, takes a copy of the protocol
2
ответ дан 23 November 2019 в 21:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: