Указатели на объекты в наборе или в векторе - это имеет значение? - PullRequest
0 голосов
/ 29 октября 2010

только что натолкнулся на ситуацию, когда мне нужно хранить выделенные в куче указатели (для класса B) в контейнере STL.Класс, которому принадлежит частный контейнер (класс A), также создает экземпляры B. Класс A сможет возвращать константные указатели на экземпляры B для клиентов A.

Теперь, имеет ли значение, если этиуказатель хранится в наборе или в векторе?Я думал о том, чтобы иметь набор только для проверки того, что дубликаты не хранятся, но поскольку адреса сохраняются, два указателя B с одинаковыми данными могут быть сохранены (если я не предоставлю класс сравнения для сравнения данных, который я предполагаю).

Есть какие-нибудь мысли на эту (довольно смутную) тему?Каковы плюсы / минусы альтернатив?Smart_pointers - это что-то, на что стоит обратить внимание?

Пожалуйста, спросите меня, если что-то непонятное необходимо, спасибо!

Ответы [ 5 ]

4 голосов
/ 29 октября 2010

Нет ничего плохого в хранении указателей в стандартном контейнере - будь то вектор, сет, карта или что-то еще. Вам просто нужно знать, кому принадлежит эта память, и убедиться, что она выпущена соответствующим образом. Выбирая контейнер, выберите контейнер, который наиболее подходит для ваших нужд. Vector отлично подходит для произвольного доступа и добавления, но не так хорош для вставки в другое место контейнера. list очень хорошо справляется со вставками, но не имеет произвольного доступа. Наборы гарантируют, что в контейнере нет дубликатов, и он отсортирован (хотя сортировка не очень полезна, если набор содержит указатели, а вы не предоставляете функцию компаратора), тогда как карта представляет собой набор пар ключ-значение, поэтому сортировка и доступ осуществляется по ключу. И т. Д. И т. Д. Каждый контейнер имеет свои плюсы и минусы, и то, что лучше всего подходит для конкретной ситуации, полностью зависит от этой ситуации.

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

Если вас беспокоит наличие множества указателей на одни и те же данные, плавающих вокруг, или у вас нет явного владельца для определенного фрагмента памяти, тогда интеллектуальные указатели являются хорошим решением. * Boost shared_ptr, вероятно, будет хорошим вариантом для использования, а shared_ptr будет частью C ++ 0x. Многие полагают, что вы всегда должны использовать общие указатели, но есть некоторые накладные расходы, и то, будет ли это лучше для вашего конкретного приложения, будет полностью зависеть от вашего приложения.

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

0 голосов
/ 29 октября 2010

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

0 голосов
/ 29 октября 2010

Если вам нужно хранить указатели в контейнерах stl, используйте shared_ptr.

Теперь набор звучит совершенно неправильно. Что ты собираешься делать с этими? Если вам нужно добавить и удалить, то список. Если вам нужно перебрать диапазон или все, то вектор. Если вам нужно получить доступ к конкретному, зная ключ, то карту. Посмотрите и на других. Один размер не подходит для всех.

0 голосов
/ 29 октября 2010

Мой ответ таков: любые решения, которые вы принимаете, должны приниматься с вашей целью.Если вам нужно правило «запрещены дубликаты», которое применяет набор, используйте набор.Если нет, то вы можете захотеть использовать вектор или любой контейнер может помочь.

Что касается smart_pointers, то да, они действительно очень полезны.Должны ли они быть использованы?Я не знаю, еще раз, я не знаю, какова ваша конечная цель или проблема, которую вы пытаетесь решить с ними.

В основном это сводится к этому.Если бы я сказал: «Я хочу использовать молоток. Что вы об этом думаете?»Вы, вероятно, скажете: «Ну, зачем, я знаю, что молотки очень хороши для сценариев с гвоздями и деревом, но они также могут быть использованы в качестве инструмента для причинения вреда людям или, возможно, в качестве книжного стенда. Послушайте, просто подождите секунду, что этоснова?Проблема в том, что я действительно не сказал, почему я хочу использовать молоток.Я не сказал, какую цель я пытаюсь достичь.

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

0 голосов
/ 29 октября 2010

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

Я не знаю, почему было бы важно хранить указатель в каком контейнере. Контейнеры на самом деле не манипулируют своими данными, они предоставляют доступ к ним только по-разному. Так что решать вам :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...