![]() |
Модераторы: bsa |
![]() ![]() ![]() |
|
SABROG |
|
||||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 1 Всего: 91 |
Предположим, что есть структура типа
Так вот как в цикле удалить указатели из этой структуры, чтобы освободить память, при этом, чтобы оставить возможность обращаться к этим указателям по имени и не городить башню типа:
Плюс с точки зрения безопасности. Я ведь могу добавить итем в структуру и забыть прописать его удаление. Я знаю одно решение, которое использует адресную арифметику и увеличивает указатель на начало первого указателя до тех пор, пока адрес не станет больше указателя на последний элемент. Но имхо это не правильно. Использовать всякие hashmap'ы я не хочу. Может просто в структуре объявить массив указателей, а в отдельной структуре описать имена каждого элемента. Когда нужен поименный доступ буду "кастовать" этот массив в структуру, когда нужно удаление - буду пробегаться по массив. |
||||
|
|||||
mrbrooks |
|
|||
![]() трололомен ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4259 Регистрация: 4.10.2006 Где: Дол Гулдур Репутация: 19 Всего: 306 |
Может просто использовать конструктор-деструктор.
|
|||
|
||||
GoldFinch |
|
|||
![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2141 Регистрация: 30.11.2008 Репутация: 6 Всего: 26 |
или писать на ЯП с автоматическим сбором мусора
|
|||
|
||||
SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 1 Всего: 91 |
А смысл, если в том же деструкторе придется прописывать многоэтажное удаление ? Намек на Java понят, но что если проекту уже несколько лет и он на C++ ![]() |
|||
|
||||
pan2004 |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 357 Регистрация: 28.7.2007 Репутация: 2 Всего: 9 |
А использовать умные указатели? Да тот же shared_ptr<> освободит от необходимости писать кучу delete.
|
|||
|
||||
SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 1 Всего: 91 |
А его можно использовать с библиотеками, которые не знают о существовании умных указателей ? Например у метода чужого класса параметр mytype * и больше никакой ? Если я получу указатель через get() и передам его в метод. Метод его поюзает и вернет управление. Все, теперь мне надо удалить указатель. Не удалится же он сам ? |
|||
|
||||
pan2004 |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 357 Регистрация: 28.7.2007 Репутация: 2 Всего: 9 |
Можно, главное чтобы эти библиотеки не брали на себя шефство над этими указателями, те например не пытались их удалять. Это безопасно, если метод не пытается сохранить этот указатель где то у себя внутри, тогда надо следить, чтобы время жизни такого "неуправляемого" указателя было не больше чем у shared. shared_ptr<> удалит объект на который он указывает сам, как только запустится деструктор последнего shared_ptr, указывающего на этот объект. |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
В деструкторе прописывается один раз, а если удалять в коде программы, то при изменении структуры надо будет найти все места, где происходило удаление. Пример какой то надуманный.. Чего от Вы не договариваете.. Также не понятно: являются ли объекты "собственностью " указателей ? если да, то почему выбрано хранение объекта в структуре по указателю, а не по значению ? какая логика должна быть при копировании структуры ? ... |
|||
|
||||
SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 1 Всего: 91 |
Там где бы я хотел применить - сохраняет внутри себя, причем пользователь может сам его удалить, либо метод сам удаляет в некоторых случаях, скажем при вызове clear() или при установке указателя на место другого указателя. Т.е. если указатель уже имеется, то он удаляется и заменяется на новый.
В принципе очистка и так в деструкторе идет, но в стороннем классе, который использует эти структуры. Место хоть и одно, но с точки зрения оптимизации 20 инструкций delete идущих подряд в бинарнике, вместо цикла с адресной арифметикой, не очень нравится. Просто сегодня увидел код, где в цикле удалялись элементы структуры с инкриментированием указателя на эту структуру. И вспомнил, что действительно бывают часто такие ситуации при написании GUI приложений, когда надо инициализировать кучу итемов и у каждого свое имя. Нет, объекты - классы сторонней библиотеки, чья реализация завуалирована и не поддается редактированию ![]() Структуры просто помещаются в массив. Предположим, каждая структура - родитель в treeview, а указатели этой структуры - детки. Все-таки давайте не отклонятся от первоначальной темы в сторону перепроектирования приложения. Проекта нет и ситуация чисто гипотетическая. Это сообщение отредактировал(а) SABROG - 30.12.2008, 13:20 |
|||
|
||||
mes |
|
||||||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
ИМХО, лучше смотреть с точки зрения логичности и подерживаемости кода.
А при чем тут реализация объектов ? Вобщем хоть и не понял что Вам надо, вот попытаюсь для начала условный набросок дать:
Это сообщение отредактировал(а) mes - 30.12.2008, 13:41 |
||||||
|
|||||||
SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 1 Всего: 91 |
Вот о чем я говорю. Метод с enum отбросил из-за некоторой кривизны доступа к именам объектов, хотя в виде класса смотрится неплохо.
Т.е. тут достаточно менять список итемов в структуре-интерфейсе. Об остальном программа заботится сама. Это сообщение отредактировал(а) SABROG - 30.12.2008, 13:55 |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
||||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 85 Всего: 196 |
![]() Если бы это написал мой подчиненны, я бы заставил переписывать... И вообще, с некоторых пор для этих целей использую std::auto_ptr. И стараюсь не юзать его с new вне классов... |
|||
|
||||
SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 1 Всего: 91 |
В каком месте ![]() А что именно не нравится, сама задача или то как я реализовал и у тебя есть третий вариант ее решения ![]() |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
Вы не учитываете выравнивание...(хотя Вам повезет, так как размер указателя на обычных архитектурах "попадает на границу выравнивания".)
А вот этого не вздумается. ) Хотя бы то, что способ использования определен "далеко" от декларации. Это сообщение отредактировал(а) mes - 30.12.2008, 18:48 |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 85 Всего: 196 |
Вернемся к исходной задаче. Тебе лень удалять кучу разных объектов, память под которые выделена динамически. Для этого лучше использовать std::auto_ptr (особенно, когда нет задачи передавать указатель за пределы объекта его содержащего). А по поводу того, что в итоге получилось - это просто непонятно что, непонятно для чего и непонятно что делает. Другими словами, это отход от приципа: "программа пишется для программиста, а не для компьютера". Может оно и оптимально по скорости, но я бы на твоем месте подумал о будущем - что ты будешь делать с этим через пару месяцев. |
|||
|
||||
SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 1 Всего: 91 |
||||
|
||||
SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 1 Всего: 91 |
Мне не лень, просто слишком много данных придется держать в памяти, чтобы не забыть где-то добавить удаление добавленного параметра. Да и задача передачи указателя за пределы объекта есть, тот код, что я написал всего-лишь отражение моих желаний.
Написал и забыл ![]() P.S.: снял пометку о решении. Раз местным гуру не нравится такой вариант, остается ждать либо другого решения, либо ответа почему подобная ситуация не должна возникать в принципе... Это сообщение отредактировал(а) SABROG - 30.12.2008, 18:29 |
|||
|
||||
mes |
|
||||||||||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
Как раз своей новой конструкцией Вы и обременили себе память.
Не понял.
Один раз написал - забыл, второй, а в третий так вылезет, что мало не покажется. ![]()
вот вот ![]() "Далеко" это как например внутри Get-функции создавать объект который должен быть удален снаружи. А "близко" это то что создано в конструкторе- удаляeтся в деструкторе. Вся реализация (а тем более с трюками) должна быть абсолютна изолирована от остальной части кода. Т.е для начала составьте интерфейс который нужен будет остальной проге, а потом реализуйте его как хотите.
Для решения нужно как минимум понять, что требуется и как это будет использовано. Это сообщение отредактировал(а) mes - 30.12.2008, 18:49 |
||||||||||
|
|||||||||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 85 Всего: 196 |
SABROG, для начала попробуй описать что ты хочешь получить в итоге (методы реализации на данном этапе не интересны).
Например, то что ты написал в первом сообщении можно сделать так:
Но я не уверен, что это все нужно городить, так как мне кажется сама идея хранения такого большого списка однотипных параметров нелогичной. Может стоит сделать как-то иначе? |
|||
|
||||
SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 1 Всего: 91 |
Предположим есть treeview, который является Property Editor'ом для какой-нибудь IDE или просто редактор БД. Несмотря на то, что каждый параметр имеет свой тип, сами итемы этого treeview - одного класса. В итоге 10 строковых параметров, 5 интовых, 4 блоба, 8 флоат - все указатели имеют один тип - элемент treeview. |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
То есть у нас есть структура которое содержит n-e кол-во наследников одного типа. Тут понятно.. Но пока видим только массив. Продолжайте. ![]() |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 85 Всего: 196 |
Аналогично |
|||
|
||||
SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 1 Всего: 91 |
Ну да, видим массив. Но массив то с ограниченным количеством элементов. Как говорится, уже нельзя всех под одну гребенку (сорри после корпоратива, мозга не варит и в квартире воняет протухшей рыбой).
Это сообщение отредактировал(а) SABROG - 30.12.2008, 21:57 |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
и что это меняет ? Разница возникнет, тогда, когда Вам 1. либо надо знать конкретный тип каждого/определенного элемента 2. либо обращаться к элементу по имени (опять же известно ли имя на момент компиляции? и полезна ли даная известность ?) |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 85 Всего: 196 |
SABROG, не вижу проблем с ограниченностью количества элементов. Почему нельзя написать в структуре mytype *items[20]?
|
|||
|
||||
SABROG |
|
||||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 1 Всего: 91 |
А параметры проверять так чтоль ?
Вместо
|
||||
|
|||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
а почему бы не root->title()->text(); или даже root()->title()->text(); ? если конечно статические имена в Вашем случае удобны чем динамические. Это сообщение отредактировал(а) mes - 31.12.2008, 12:41 |
|||
|
||||
SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 1 Всего: 91 |
С массивом я такое смогу провернуть только если создам класс как уже писали тут http://forum.vingrad.ru/index.php?showtopi...t&p=1743811 auto_ptr использовать опасно т.к. treeview может сам удалить указатель. Это сообщение отредактировал(а) SABROG - 31.12.2008, 13:11 |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
а "вручную" как Вы узнаете что treeview уже удалил элемент и его не надо удалять? пока Вы не привели ни одного довода, для создания той структуры о которой идет речь. Как я понял у Вас есть treview с элементами. Вы делаете его маппинг. Т.е Ваша структура служит посредником для доступа к определенным полям. В таком случае использование открытой структуры, внесет Вам большой ряд проблем. Если доступ к элементам будет "разгружен" функцией, то Вы отгородите реализацию "компонента" от остальной программы. Все таки до сих пор не понятно, важно ли для самой программы (ее бизнес-логики) знание статического имени. можно ведь вместо root()->title()->text(); использовать динамическое имя root()->node(title)->text(). ну а можно статическое root()->node<title>()->text(). (для удобства только придется у Александреску позаимствовать шаблоны TypeList и некоторые другие) Это сообщение отредактировал(а) mes - 31.12.2008, 14:06 |
|||
|
||||
SABROG |
|
||||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 1 Всего: 91 |
Метод setItem устанавливает указатель типа treeviewitem в treeview, при этом treeview delete'ит старый указатель (если итем подменяется новым) и ставит новый. Для самой программы - не важно. Её хоть на опкодах пиши. Правда выйдет подольше. Это я к теме о доступе к массиву указателей по индексам. Как вариант конечно можно еще просто комментарии вставлять, типа:
"<title>" это какой тип ? |
||||
|
|||||
mes |
|
||||||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
Вы не так поняли, о чем я говорил. Я интересовался нужно ли программе знать, что бывает title. Или достаточно знать что есть список свойств.
в данном случае программе известно, что бывает title. a в данном :
нет. Первый статичный и предоставляет контроль типов и операций, а второй более динамичный и позволяет на лету менять набор полей в структуре. имя класса, примерно (не точно помню названия шаблонов в библиотеке, а смотреть лень ![]()
но можно подобное и с енумом/интом. Зависит от целей. |
||||||
|
|||||||
![]() ![]() ![]() |
Правила форума "C/C++: Для новичков" | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Для новичков | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |