Страница 1 из 3

Отслеживание ссылок

Добавлено: 13 фев 2009, 07:17
atavin-ta
Есть динамический массив объектов. На некторые из этих объектов есть указатели в других объектах. Причём, объекты, содержащие указатели, могут быть того же или другого типа и находиться в данном массиве, в другом массиве того же типа, в массиве (статичнском или динамическом) другого типа или быть самостоятельными (иметь индивидуальные идентификаторы в исходнике данной проги). Требуется в самих объектах или в массиве отследить подобные указатели. Задача двойная:
1. удалить все элменты, на которые нет указателей,
2. при изменении адреса исправить все указатели.
Причём, первый пункт должен выполняться только по специальному требованию. Алгоритм должен справляться с циклическими и перекрёстными ссылками. Факт наличия только перекрёстных ссылок между имеющими один тип элемнтами массиво одного типа или одного массива не должен мешать удалению, но при наличии иных ссылок удаление происходить не должно.

Re: Отслеживание ссылок

Добавлено: 13 фев 2009, 11:31
Romeo
Это задачка на "потренироваться" или характеристики реальной системы?

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

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

Re: Отслеживание ссылок

Добавлено: 13 фев 2009, 11:55
atavin-ta
&quot писал(а):Это задачка на "потренироваться" или характеристики реальной системы?
Задачи реального проекта, повисшего из-за незнания, как их решать.
&quot писал(а):Изменение дизайна системы, вместо имплементации текущего поведения, будет на порядок более простым с точки зрения кодинга и поддержки и покажет более высокие результаты производительности в рантайме.
Все изменения только в rutimе.

Re: Отслеживание ссылок

Добавлено: 13 фев 2009, 12:52
Airhand
Тебе Romeo уже сказал: пользуйся автопоинтерами или boost.

Re: Отслеживание ссылок

Добавлено: 13 фев 2009, 15:40
Romeo
&quot писал(а):Все изменения только в rutimе.
Это к чему относится и какая связь этих слов с моими текстом, который ты поместил выше в квоты?

Re: Отслеживание ссылок

Добавлено: 16 фев 2009, 04:57
atavin-ta
&quot писал(а):Это к чему относится и какая связь этих слов с моими текстом, который ты поместил выше в квоты?
Твой текст я понял как упоминание подходов к отслеживанию ссылок при реструктуризации проекта, а у меня задача на этапе исполнения отследить ссылки при изменнении данных. Если я чего-то не так понял, попробуй растолковать.

Re: Отслеживание ссылок

Добавлено: 17 фев 2009, 09:57
Naeel Maqsudov
atavin-ta писал(а): 1. удалить все элменты, на которые нет указателей,
Так как Вы описали - это слишком сложно для вспомогательной задачи (не думаю, что описанная задача является самоцелью). Обычно в таких случаях используют специальные функции - фабрики классов.
У фабрики есть статическая переменная (сохраняемая между вызовами) которая подсчитывает количество ссылок на данный объект. Если ссылок еще не было, то фабрика создает новый экземпляр, всякий раз при запросе новой ссылки счетчик увеличивается. Когда объект не нужен фабрикавызывается с указанием "отпустить" указатель. Как только счетчик дошел до нуля, то фабрика вызывает деструктор и освобождает ресурсы занятые объектом.
Кстати, тот самый динамический массив ссылок о котором шла речь в самом начале, как раз и должен обслуживаться фабрикой. Но просто к указателю на объект добавьте еще счетчик. Т.е. можно сделать универсальную фабрику (не для 1 класса, а для сразу нескольких)
atavin-ta писал(а): 2. при изменении адреса исправить все указатели.
Опять же решаемо через фабрику. Пусть все кому нужен объект вызывают фабрику, надо только добавить еще один параметр, который указывает на то, нужен ли новый указатель, или хочется получить копию старого. Например, некая функция хочет поработать с объектом №8. Она не должна хранить указатель, а всегда брать его у фабрики и помещать в переменную, а далее использовать. Если по какой-либо причине объект №8 будет пересоздан, то фабрика отдаст уже измененный указатель.

Re: Отслеживание ссылок

Добавлено: 17 фев 2009, 19:44
Romeo
Naeel Maqsudov, фабрика, как шаблон проектирования, не должна обеспечивать рефкаунтинг. Либо, если она это делает, то называть её фабрикой уже нельзя. Наверное, в таком случае подойдёт имя менеджер.

Моё предложение было куда проще. А именно сделать легковесный темплейт враппер, который хранит указатель на структурку, в которой содежится указатель и счётчик ссылок на этот указатель. В конструкторе счётчик++, в деструкторе счётчик-- и если счётчик == 0 то delete указатель.

Как вариант, если приемлемо использование boost'а, то использовать авторефепоинтер из этой библиотеки, который делает то же самое.

Кстати, ни авторефпоинтеры, ни менеджер не решит проблему циклических ссылок. Для того, чтобы избежать циклических ссылок нужно решить какие объекты будут содержать голые поинтеры, а в каких местах поинтеры нужно "держать". Это куда проще, чем применять какие-либо алгоритмы из теории графов для отслеживания циклов.

Re: Отслеживание ссылок

Добавлено: 18 фев 2009, 08:50
atavin-ta
Что такое фабрика и рефкаунтинг? Когда и для чего нужно? Как реализовать? Где взять серьёзну книгу с текстом и примерами на эту тему?

Re: Отслеживание ссылок

Добавлено: 18 фев 2009, 09:38
atavin-ta
&quot писал(а):Naeel Maqsudov, фабрика, как шаблон проектирования, не должна обеспечивать рефкаунтинг. Либо, если она это делает, то называть её фабрикой уже нельзя. Наверное, в таком случае подойдёт имя менеджер.

Моё предложение было куда проще. А именно сделать легковесный темплейт враппер, который хранит указатель и счётчик ссылок на этот указатель. В конструкторе ссылка++, в дестректоре ссылка-- и если ссылка == 0 то delete this.

Как вариант, если приемлемо использование boost'а, то использовать авторефепоинтер из этой библиотеки, который делает то же самое.

Кстати, ни авторефпоинтеры, ни менеджер не решит проблему циклических ссылок. Для того, чтобы избежать циклических ссылок нужно решить какие объекты будут содержать голые поинтеры, а в каких местах поинтеры нужно "держать". Это куда проще, чем применять какие-либо алгоритмы из теории графов для отслеживания циклов.
Мне надо не только сосчитать ссылки, но и найти все ссылки.