Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Для новичков > Смартпоинтеры в STL. |
Автор: NightmareZ 18.3.2010, 04:27 | ||
О чём думали дизайнеры STL, создавая в нём единственный тип смартпоинтеров, который при том (что он единственный) нельзя использовать в контейнерах? Мне нужен полиморфизм для объектов в коллекции (например, в векторе). Просвятите неразумного шарписта, как в C++ (без всяких бустов и нового Стандарта) это сделать? Не указатели же на базовый класс хранить?
|
Автор: NightmareZ 18.3.2010, 04:53 | ||
В идеале я бы хотел вот такого, но из стандартной поставки:
|
Автор: borisbn 18.3.2010, 07:29 |
И в любом случае в Base нужно определить виртуальный деструктор |
Автор: NightmareZ 18.3.2010, 08:06 | ||
Виртуальный деструктор тут нафик не нужен. Добавлено через 2 минуты и 7 секунд Как нет. А auto_ptr?
Вопрос в том, как люди обходятся? Пишут своё? Почему нет в стандартной библиотеке ничего подходящего? |
Автор: rgsoftware 18.3.2010, 08:18 | ||
Ну, потому что Стандартная библиотека в нынешнем виде -- это фиксация на бумаге 1998 года, тогда ещё народ, видимо, коллективно не созрел до смартпоинтеров в коллекциях. А потом дописали буст... Если по каким-то причинам буст не устраивает, надо просто вырезать кусок, ответственный за shared_ptr, и использовать у себя с чистой совестью ![]() |
Автор: azesmcar 18.3.2010, 08:39 | ||||
имелось ввиду тех, о которых ты спрашивал. Про auto_ptr ты сам написал, и сам же сказал почему он не подходит.
нет, почему же..люди уже давно используют буст ![]() boost смело можно считать стандартной библиотекой. STL писали давно, в нее много чего не вошло. он определится автоматически как виртуальный, так как деструктор базового класса виртуальный. Добавлено через 13 минут и 13 секунд подожди, чего-то не так понял (я думал речь о наследниках)..так он же виртуальный. |
Автор: bsa 18.3.2010, 11:30 |
Ты в этом уверен на 100%? Потому что обычно, когда есть виртуальные методы, виртуальный деструктор нужен. Другими словами, если потомки класса Base имеют хоть один атрибут, то без виртуального диструктора твой первый пример приведет к утечкам памяти. Напиши свой вариант shared_ptr внутри #ifdef/#else/#endif, что позволит использовать твой код юзая смартпоинтеры нового стандарта лишь задефайнив определенный макрос. |
Автор: azesmcar 18.3.2010, 11:33 | ||||||
Мне пора в отпуск..
я функцию Do за деструктор принял ![]() наконец понял о чем речь. можно сказать он нужен всегда (когда есть виртуальные методы), а тут тем более, иначе в строке
будет UB. gcc даже warning выдает на классы, у которых есть виртуальные методы и не виртуальный деструктор. |
Автор: djamshud 18.3.2010, 12:21 |
Сишарперы настолько суровы, что не в состоянии прикрутить к своему проекту любой готовый sharedptr, не говоря уже о том, что бы написать его самому за десять минут? Нет его в STL, сами написали, так чего сопли по форумам размазывать? |
Автор: NightmareZ 18.3.2010, 13:20 | ||
Уверен. Что за атрибут? Где тут утечка? |
Автор: azesmcar 18.3.2010, 13:28 |
имелся ввиду любой атрибут класса, которого в примере нет, но в реальной жизни может и быть. скорее всего это утечка, так как не вызовется деструктор наследника, но стандарт не гарантирует определенного поведения, при удалении объекта класса, не имеющего виртуального деструктора через указатель базового. |
Автор: bsa 18.3.2010, 13:36 |
Если мы рассматриваем конкретно тот пример, который иллюстрирует проблему, а в реальной программе у тебя есть виртуальный деструктор, то нет проблем. Считай, это напоминание. |
Автор: JackYF 18.3.2010, 19:58 |
Как тут уже сказали, есть буст и (когда-нибудь "релизнется" же он ![]() |
Автор: GoldFinch 18.3.2010, 20:15 |
JackYF, в следующем году релизнется: http://herbsutter.wordpress.com/2010/03/13/trip-report-march-2010-iso-c-standards-meeting/ |
Автор: NightmareZ 19.3.2010, 03:08 | ||
Ну так деструктор вызываться должен для того, чтобы что-то в классе удалить/почистить/закрыть/etc., а у меня же класс пустой. |
Автор: azesmcar 19.3.2010, 06:34 | ||||
Повторяю еще раз, утечка памяти это частный случай реализации.
|
Автор: borisbn 19.3.2010, 07:07 | ||
а Child1::vf_ptr ? |
Автор: JackYF 19.3.2010, 12:44 |
![]() Спасибо за ссылку, но это ещё ничего не значит. Изначально его планировали релизнуть до 2009, и сейчас у них тоже только планы ![]() |
Автор: Леопольд 19.3.2010, 15:25 |
Тут два варианта. Либо открытый виртуальный деструктор, если собираемся уничтожать объект по ссылке/указателю базового класса (интерфейса). Либо защищённый невиртуальный деструктор, он не даст этого сделать. |
Автор: azesmcar 19.3.2010, 15:37 | ||||||
![]() так что ли?
так он и этого тоже не позволит
может речь идет о защищенном наследовании? В таком случае совсем непонятно зачем там нужен полиморфизм. |
Автор: Леопольд 19.3.2010, 15:38 | ||||
Добавлено @ 15:45 Конечно не позволит. Подразумевалось что базовый класс абстрактный. Добавлено @ 15:47 Мне удобнее считать абстракный класс интерфейсом. В C# именно так и сделано, насколько я знаю. Добавлено через 13 минут и 4 секунды Нет, так:
|
Автор: azesmcar 19.3.2010, 15:54 | ||||
понял что ты имеешь ввиду, вовсе не обязательно чтобы он был абстрактным, можно например так
не совсем так, на самом деле интерфейс - это класс, который описывает только интерфейс, который нужно реализовать, т.е. имеет одни только чисто виртуальные функции. |
Автор: Леопольд 19.3.2010, 15:56 | ||
![]() |
Автор: azesmcar 19.3.2010, 15:58 |
нет, просто опечатка, исправил. |
Автор: Леопольд 19.3.2010, 16:02 | ||
|
Автор: azesmcar 19.3.2010, 16:03 | ||
т.е. по твоему абстрактные классы не нужны? |
Автор: Леопольд 19.3.2010, 16:03 |
Тогда я не понял что ты имел ввиду. Разверни, будь добр... Добавлено @ 16:05 По моему надо стараться избегать помещать данные и не чистые функции в абстрактные классы. По крайней мере мне лично, так проще... |
Автор: azesmcar 19.3.2010, 16:06 |
да тоже самое, класс, который не инстанцируется, абстрактный он или нет совершенно не важно. |
Автор: Леопольд 19.3.2010, 16:07 | ||
|
Автор: azesmcar 19.3.2010, 16:09 |
std::unary_function, std::binary_function ... |
Автор: Леопольд 19.3.2010, 16:14 |
Точно, это и есть претенденты на protected деструкторы... ![]() Добавлено через 1 минуту и 19 секунд Ты меня понял быстрее чем я тебя... ![]() |
Автор: NightmareZ 19.3.2010, 16:31 |
Ну так, если он всё-таки будет пуст, виртуальный деструктор не нужен? |
Автор: bsa 19.3.2010, 16:56 | ||
|
Автор: mes 19.3.2010, 18:14 | ||
Позвольте узнать на чем Вы, по Вашему мнению, экономите, имея виртуальные функции и не делая деструктор виртуальным ? |
Автор: NightmareZ 20.3.2010, 03:14 | ||
Дело не в экономии. Дело в понимании. Мне вот совершенно непонятно, почему в моём коде нужен виртуальный деструктор. А люди, вместо того, чтобы сказать, что в этом коде он нужен или не нужен, додумывают к коду какие-то дополнения.... мол, а вот если бы так да эдак, то точно нужен бы был. |
Автор: W4FhLF 20.3.2010, 08:06 | ||
Тебе совершенно понятно объяснили, что в твоём случае имеет место быть UB и данных, которые ты предоставил недостаточно. Чтобы сказать будет или нет утечка можешь засунуть релиз в дизассемблер и посмотреть, что нагенерил компилятор. Или написать ключевое слово virtual и жить спокойно. |
Автор: borisbn 20.3.2010, 08:38 | ||||
сделай
а потом добавь
и повтори то же самое |
Автор: NightmareZ 20.3.2010, 12:16 |
Сделал. И что? |
Автор: borisbn 20.3.2010, 12:21 |
![]() ![]() по идее у тебя в первом случае (без виртуального деструктора) должна была закончиться память. |