| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > Умные указатели (smart pointers), auto_ptr и т.п. |
| Автор: SABROG 14.4.2008, 17:55 |
| Есть класс, который генерит древовидную структуру используя обычные указателями. Структура довольно сложная и громоздкая, я боюсь где-то могу забыть прописать удаление указателя в деструкторе класса. Посему назрела мысль использовать "умников-стрелочников". Но насколько я понял пободные смартпоинтеры действуют по принципу - вышли из области видимости - сработал деструктор и сами удалились. Но у меня ситуация такая, в конструкторе создаются указатели, но при выходе из конструктора они должны остаться валидными и удалиться только в деструкторе моего класса. Как в таком случае применить смарт-поинтеры если их участь - подохнуть точно также как локальный объект созданный во временном стеке, теряется смысл ? |
| Автор: Daevaorn 14.4.2008, 18:01 |
| Всё зависит от типа умного указателя. Далеко не все общедоступные реализации "умирают" при выходе из области видимости. Например boost::shared_ptr |
| Автор: SABROG 14.4.2008, 18:11 |
| Уж очень не хочется использовать boost в своей программе. К тому же я так понимаю если указатель даже и shared, то компилятор сам ну ни как не определит в какой момент мне нужно удалять его, пока я вручную не задам аналог delete в нужном месте. А это опять же сводит на нет мою идею. |
| Автор: Dreamer_0x01 14.4.2008, 18:15 |
| Раз указатели создаются в конструкторе, почему бы не объявить их как переменную класса в виде умного указателя? |
| Автор: SABROG 14.4.2008, 18:17 | ||||
Нельзя, они динамические. Зависит от количества записей в базе данных. И содержит все эти указатели вектор, который является членом класса. Скорее не религия, а поговорка о пушках и воробьях.
А пример можно ? |
| Автор: vinter 14.4.2008, 18:31 |
создаешь shared_ptr и инициализируешь его обычным указателем, кол-во ссылок становится равным 1, при любом копировании( в том числе и инициализирующем) кол-во ссылок инкрементируется, при выходе любой копии за границу видимости, кол-во ссылок уменьшается на 1. так вот когда кол-во ссылок становится равным 0, вызывается delete для указателя который обернут в shared_ptr. |
| Автор: SABROG 14.4.2008, 18:40 | ||||
А как это сработает в таком виде: //псевдо-код
Когда поинтеры убьются, когда убьется otherClass или вызовется delete для A ? |
| Автор: Rififi 14.4.2008, 18:47 |
Boost Smart Pointer является совершенно самостоятельной библиотекой и даже не требует связывания на этапе линковки (вся функциональность содержится в заголовочных файлах) Это к вопросу о пушках. |
| Автор: Fin 14.4.2008, 19:31 | ||
Можно использовать ּSTL-овские контейнеры. Только в них не заносить сами указатели, а записи. Что то типа такого
Тогда уже сам контейнер будет заботится об удалении записей. |
| Автор: Mephisto 14.4.2008, 19:36 | ||
Если ты создашь вектор auto_ptr'ов, то последующий занесенный auto_ptr будет копироатся из конструктора в список. А при копировании auto_ptr класс источник теряет ссылку. Так что выйдя з апределы конструктора ты ничего не потеряешь ибо вызовется деструктор у класса указатель из которого уже извлечен. Т.е. при копировании из одного auto_ptr в другой ты не получишь 2 ссылки на auto_ptr. В таком случае только последний классс будет иметть реально ссылку которую прибьет в деструкторе. Короче кто последний влез, того и тапки. Добавлено через 59 секунд Fin, ага. И туда можно вогнать auto_ptr |
| Автор: vinter 14.4.2008, 19:58 |
что то я не совсем понял твой псевдокод |
| Автор: maxim1000 14.4.2008, 20:19 |
не, shared_ptr - это уже указатель (по крайней мере, по смыслу), так что достаточно list<shared_ptr> |
| Автор: Rififi 14.4.2008, 20:21 |
... в программе очень скоро начнутся проблемы Подробности почему - читать в книгах зубров (Мейерс/Саттер) Добавлено через 58 секунд PS. собственно, ты дальше сам рассказал почему. |
| Автор: SABROG 14.4.2008, 20:22 |
Т.е. если вместо указателей запхнуть в контейнер auto_ptr'ы, то при удалении контейнера для каждого из объекта auto_ptr'a вызовется деструктор и освобождение памяти ? |
| Автор: vinter 14.4.2008, 20:23 |
кстати вполне возможно, что этот не скомпилируется. |
| Автор: Mephisto 14.4.2008, 20:56 |
Кстати да, возможно. |
| Автор: SABROG 14.4.2008, 21:14 | ||||
Так оно и есть:
А с shared_ptr тоже самое будет ? |
| Автор: bsa 14.4.2008, 21:20 |
| SABROG, auto_ptr нельзя использовать в контейнерах. Просто работа с контейнерами подразумевает нормальную логику работы оператора присваивания и конструктора копирования. А у auto_ptr эти функции являются перемещающими. Другими словами, auto_ptr надо использовать при возврате функцией ссылки на объект, чтобы он сам удалился когда будет не нужен, а также для хранения указателей на динамически конструируемые поля классов. У boost::shared_ptr логика копирования классическая. Поэтому его можно хранить в контейнерах. |
| Автор: SABROG 14.4.2008, 21:38 | ||
| Что-то мне подсказывает, что выцепить shared_ptr отдельно от буста будет сложно... //shared_ptr.hpp
|
| Автор: Fin 14.4.2008, 21:43 | ||||
Вот мой пример. Как то я для себя писал "умный указатель" который подсчитывает сам количество ссылок и если надо удаляет.
получаем
|
| Автор: Rififi 14.4.2008, 21:47 | ||
Это будет сложно только до того момента, пока ты не познакомишься с http://www.boost.org/doc/libs/1_35_0/tools/bcp/bcp.html |
| Автор: bsa 14.4.2008, 21:48 |
| SABROG, а почему ты так боишься самого буста? Установи его и используй. Какие проблемы? Тем более, что вроде как этот shared_ptr в стандарт С++ должен войти, как и некоторые другие вещи из буста. |
| Автор: SABROG 14.4.2008, 21:49 | ||||||
Уже познакомился, спс. Просто я скачал исходники через SVN, а этот BCP надо собирать...
А потому, что программа кроссплатформенная и возможно я буду выкладывать ее исходники и мне бы не хотелось заставлять других программистов устанавливать boost только ради того, что я использую shared_ptr... |
| Автор: bsa 14.4.2008, 21:50 | ||
Зачем, если не секрет? Чем тебя стабильная версия не устроила? |
| Автор: Rififi 14.4.2008, 21:55 |
| bsa, Иногда в в trunk'е появляются различные полезные классы/библиотеки которых долго ждать в релизе (как например это было с circular_buffer etc), а учитывая, насколько может затянуться релиз... |
| Автор: bsa 14.4.2008, 21:59 | ||
Тут речь идет о shared_ptr, которому уже 100 лет в обед. |
| Автор: SABROG 14.4.2008, 22:02 | ||||
Я руководствовался такой логикой, раз SVN значит исходники, а раз исходники, значит можно выдрать shared_ptr и желательно последней версии, если он вообще менялся |
| Автор: Rififi 14.4.2008, 22:04 |
| bsa, ну если про shared_ptr, тогда, наверное, преимуществ нет. А вообще, вотЪ |
| Автор: bsa 14.4.2008, 22:07 |
| SABROG, буст в исходниках и поставляется. Поэтому, когда хочется по быстрее установить гимор возникает - компилится сволочь долго (не всем только shared_ptr нужен)! |
| Автор: SABROG 14.4.2008, 22:14 |
| Похоже будет проще взять версию Fin'a (за что ему спасибо) чем лезть через терни к звездам. |
| Автор: Mephisto 14.4.2008, 22:32 | ||
Поправте меня если я не прав. Но насколько я знаю буст как раз и анонсирует то что все их классы поддерживают только стандарт С++. |
| Автор: vinter 14.4.2008, 22:38 | ||
буст все же стороння либа, то что содержится там не обязательно войдет в стандарт, но по крайней мере в boost tr1 содержится то что, должно быть в std::tr1 |
| Автор: bsa 14.4.2008, 22:58 | ||
Сам то понял, что сказал? Я тут недавно прочитал про то, зачем собственно этот буст был создан. Смысл такой, это что-то вроде бета-версии новых компонентов стандартной библиотеки С++. Далеко не все войдет в стандатр, но наиболее часто используемые вещи войдут. |
| Автор: SABROG 15.4.2008, 08:35 | ||
Как я и думал "через терни к звездам", не собирается буст 1.35.0:
Использую mingw 3.4.5. Хотелось бы мне знать, что скрывается за этими значками вопросов.... |
| Автор: Lazin 15.4.2008, 09:41 | ||||
| SABROG, для shared_ptr ничего собирать не надо... boost я использую на работе а у нас здесь к надежности софта очень высокие требования =) Добавлено через 2 минуты и 20 секунд
питон не установлен, boost::python поэтому не собирается, все остальное собралось =) |
| Автор: SABROG 15.4.2008, 10:36 | ||
Дело в том, что boost не имеет собранной утилиты BCP в исходниках, а она мне нужна, чтобы выцепить shared_ptr. Конечно, как вариант, можно поискать уже собранную, но я думал будет легче собрать буст "на будущее". Вечером буду смотреть копать дальше как питон подключать, странно, что в мануале не дали ключи к bjam'у. |
| Автор: UnrealMan 15.4.2008, 13:07 | ||
Замечательный пример того, что велосипедам лучше предпочесть нормальные широкоизвестные либы. Твой код просто ужасен: пользователь никак не может проверить указатель на равенство нулю, не может разыменовать и скопировать оператором присваивания константный указатель, и есть случай, когда программа из-за твоего указателя может попросту упасть. Ну и инкапсуляция тут тоже хромает (см. метод get). В топку такой класс. |
| Автор: Fin 15.4.2008, 21:34 |
| UnrealMan, Может и в топку. Он в свое время отработал нормально и без притензий. Я никого не заставляю использовать этот класс, просто показал, что можно работать. Так что, как говорится в одной очень известной лицензии AS IS. |
| Автор: SABROG 16.4.2008, 10:30 | ||
Сам питон у меня стоит, вчера проверил. Может ему исходники нужны ? |
| Автор: Lazin 16.4.2008, 10:55 |
| Ему нужно переменную окружения создать PYTHON_PATH вроде-бы... Если тебе не нужен boost::python, то можно и не собирать, все остальное и так уже собрано |