Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Общие вопросы > Умные указатели |
Автор: Tiarwe 25.1.2013, 18:37 |
Здравствуйте! Изучаю умные указатели и что-то совсем запутался... Вначале опишу, что мне нужно. Есть класс Book и vector из указателей на эти книги. Вот захотелось мне, чтобы это были не обычные указатели, а умные... 1) В чём разница между shared_ptr и auto_ptr? Правильно ли я понимаю, что при auto_ptr на объект может ссылаться лишь один указатель, в то время как при shared_ptr - множество (т.к. идёт подсчёт ссылок)? При этом, если auto_ptr перестаёт указывать на объект, то он уничтожается? Ровно как и shred_ptr, когда кол-во ссылок равно 0? 2) Вернёмся к вектору. Пускай в нём 1000 умных указателей на объекты. И мне например захотелось удалить 200 объектов... Т.е. мне надо всего-лишь удалить указатели из вектора и больше ни о чём не беспокоиться? 3) Или на примере игры... есть Object и вектор из 100 Target'ов. Object имеет в себе указатель на один из Target'ов... Эти самые 100 Target'ов должны быть именно shared_ptr, т.к. на них ещё могут ссылаться из вне? В общем, каша в голове ![]() |
Автор: bsa 25.1.2013, 23:12 |
Tiarwe, auto_ptr такая своеобразная штука, что лучше ей не пользоваться. Если не знаешь для чего она нужна. Сейчас ее имеет смысл использовать только для контроля времени жизни динамического объекта по типу автоматических. Хотя для этого есть (в boost) более подходящая штука - scoped_ptr. Которая ведет себя более предсказуемо без чтения документации. |
Автор: EvilsInterrupt 26.1.2013, 16:14 |
Tiarwe, Читай книгу Джосьютиса "Стандартная библиотека C++". Там описан std::auto_ptr во всех красках, описаны его ограничения и его возможности, а также нюансы. После его описания в это книге приведен пример кода умного указателя с подсчетом ссылок. |
Автор: EvilsInterrupt 26.1.2013, 23:43 |
Tiarwe, Я бы юзал не вектор указателей, а список указателей. Посмотрите в сторону других контейнеров отличных от std::vector, к примеру std::list. Во внутренней реализации этого контейнера как правило участвуют указатели( не те что хранятся в этом контейнере, в контейнере может храниться любой тип хоть SuperPuperMatreshka). Обратите внимание на слово "complexity" http://en.cppreference.com/w/cpp/container Добавлено через 1 минуту и 34 секунды А вот другая http://upload.cppreference.com/mwiki/images/e/e7/container-library-overview-2012-12-27.pdf |
Автор: borisbn 27.1.2013, 18:01 | ||
EvilsInterrupt, в чём сермяжная правда отказа от вектора? Если уж так любишь ссылаться на книги, почему не привести цитату из Майерса:
За точность цитаты не ручаюсь, за смысл - да |
Автор: mes 27.1.2013, 19:07 | ||
![]() ![]() ![]() |
Автор: Dem_max 27.1.2013, 19:53 |
Почитай тут все расжевано http://www.rsdn.ru/article/cpp/smartptr.xml |
Автор: EvilsInterrupt 28.1.2013, 01:16 | ||||||
Это если не знать! Вектор как правило имеет смысл выбирать если нужно непрерывную область, так сказать C-стайл, сейчас его вроде как std::array может заменить в этом, судя по описанию на cppreference. Более того в постановке задачи:
и:
Ни одного намека на то что человеку нажно хранить книги в С-подобном виде, т.е. последовательно в файле. Зато указано 1000 !!!! Т.е. человек предполагает что ему надо будет достаточно часто вставлять. Другое из постановки задачи:
Вы все еще уверены в векторе? Удалить 200 штук, добавить 1000... |
Автор: borisbn 28.1.2013, 09:16 | ||||||
1) то, что в векторе память непрерывная - спорить глупо, но его чаще выбирают по другим причинам (правда, являющимся следствием непрерывности) - random acces за постоянное время и т.п. 2) std::array заменил массивы типа
а ни разу не вектор
По поводу добавить - уверен: http://liveworkspace.org/code/2eY9uN$9 По поводу удалить - подумай во над чем: прежде чем удалить элемент из контейнера его нужно там найти. Тест поиска элемента в векторе и в листе написать ? или и так понятно ? |
Автор: EvilsInterrupt 28.1.2013, 10:37 |
borisbn, Вы правы! Спасибо за аргументацию, которую можно "пощупать" и "потрогать". Нельзя мне в 2 ночи посты писать, каюсь! ;) |
Автор: mes 28.1.2013, 19:49 | ||
и это еще .reserve не использован )) справедливости ради надо отметить, большая разница, вставлять в конец или в начало.. |
Автор: bsa 29.1.2013, 14:19 | ||
Если честно меня удивляет, почему разработчики STL не сделали такую простую штуку, как возможность добавлять в начало вектора с такой же сложностью, как и в конец. Реализуется это всего лишь одним дополнительным указателем внутри класса и тройкой методов (reserve_front(), push_front(), pop_front()). |
Автор: baldina 29.1.2013, 14:44 | ||
vector должен быть непрерывным от &v[0] Добавлено @ 14:47 есть же deque<>, тут вам и такая же временная сложность, и добавление в начало. лишь непрерывность не гарантирована |
Автор: bsa 29.1.2013, 15:43 | ||
А кто мешает? Просто сейчас добавление в начало всегда приводит к сдвигу всех элементов, а в случае с дополнительным указателем - сдвигалось бы только начало массива (если резерв перед данными есть):
Если data_end_ == data_beg_, то вектор пуст Если area_end_ == area_beg_, то вектор не имеет резерва (и пуст). Если area_beg_ < data_beg_, то у вектора есть резерв перед началом Если data_end_ < area_end_, то у вектора есть резерв после конца Таким образом, сложность добавления в начало была бы равна сложности добавления в конец. |
Автор: baldina 29.1.2013, 18:00 |
хитрО ![]() |
Автор: bsa 29.1.2013, 19:51 |
Да ничего хитрого. Оптимизация добавления в конец именно так и сделана. Почему бы не добавить еще и оптимизацию добавления в начало? Не думаю, что еще один указатель сильно много займет ресурсов. А вот выигрыш по скорости добавления в начало был бы ощутимым. |
Автор: volatile 29.1.2013, 23:55 |
Думаю что вектор не проектировался как контейнер с оптимизацией добавления в конец. Просто это получилось само-собой. А оптимизация добавления в начало, сама собой не получилась ![]() Если вы считаете что часто нужно такое, можно сделать свой адаптер к вектору (думаю не много кода будет). Хотя честно, говоря не вижу серьезных причин, почему бы в таком случае, просто не использовать дек... |
Автор: mes 30.1.2013, 08:43 |
![]() Добавлено через 25 секунд ![]() ![]() |