E>Что говорит теория на этот счет? как правильно реализовать такие связи между объектами?
В Java/Net такой проблемы нет. Там объявляется мусором весь граф объектов незацепленный за root. В COM такое решается подсчетом ссылок именно у "Фирмы". В остальных случаях, зависит от стиля программирования и языка.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: Как правильно реализовать иерархическую структуру объ
Та это же то же самое что и у меня в примере.
В чем разница?
Если я создам объект Company, он при выходе не освободит память, так как ссылка на него хранится в объекте Department
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: Как правильно реализовать иерархическую структуру объект
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, pt4h, Вы писали:
L>>>А не основании чего вы сделали вывод, что кол-во объектов будет большим. В исходном посте никакого намека на это я не увидел.
P>>Прямого текста о большом количестве объектов действительно нет, вы правы. Однако, если бы автору исходного сообщения не важно было бы количество объектов и объем используемой ими памяти, то зачем ему беспокоиться о сборке объектов? То есть, я скорее сделал предположение относительно количества объектов... Возможно я и не прав на этот счет.
L>Неверное рассуждение. Автор исходил из предпосылки, что "зацикленные" ссылки есть проблема. Ты эту проблему попытался решить. Но решать эту проблему необходимости не было, в силу того, что проблемы в реальности не существует (сборщик мусора прекрасно справляется с циклическими ссылками).
Согласен. GC убьет все целиком (если на цикл нет ссылки из корня) или ничего если объекты имеют циклические ссылки...
Re[2]: Как правильно реализовать иерархическую структуру объ
Здравствуйте, GlebZ, Вы писали:
GZ>В Java/Net такой проблемы нет. Там объявляется мусором весь граф объектов незацепленный за root. В COM такое решается подсчетом ссылок именно у "Фирмы". В остальных случаях, зависит от стиля программирования и языка.
В том-то и проблема "Фирма" и "Отдел" — это СОМ-объекты.
У объекта "Отдел" есть такой метод:
Здравствуйте, es3000, Вы писали:
ANS>>А как ты определяеш удалился он из памяти или нет?
E>В деструторе делаю запись в лог-файл. Ни один деструктор не вызывается E>Вообще я пишу компоненты на С++
1.) а деструктор виртуальный? можно вообще код глянуть?
2.) если управление памятью делается вручную, то причем здесь цикличность ссылок и GC ? ты уверен, что сам delete вызываешь нормально, который в свою очередь делитит вложенные объекты?
Re[9]: Как правильно реализовать иерархическую структуру объ
Здравствуйте, ika, Вы писали:
ika>1.) а деструктор виртуальный? можно вообще код глянуть? ika>2.) если управление памятью делается вручную, то причем здесь цикличность ссылок и GC ? ты уверен, что сам delete вызываешь нормально, который в свою очередь делитит вложенные объекты?
Код почти весь уже привел
Так выглядит главный модуль программы:
рабФирма = new Т_Фирма
рабФирма.AddRef()
....
рабФирма.ReleaseRef(); // в этом месте проблема
рабФирма = null;
Delete я не вызываю, он должен вызваться в методе ReleaseRef. В общем то и все. Плюс у каждого есть деструктор, который делает только ReleaseRef для вложенного объекта.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: Как правильно реализовать иерархическую структуру объ
Здравствуйте, es3000, Вы писали:
E>То есть этот метод как раз и увеличивает счетчик ссылок.
В данном случае, ссылки от подчиненных объектов должны подсчитываться у объекта "Фирма". Посмотри что такое аггрегация в COM.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: Как правильно реализовать иерархическую структуру объ
GZ>В данном случае, ссылки от подчиненных объектов должны подсчитываться у объекта "Фирма". Посмотри что такое аггрегация в COM.
Что такое аггрегация знаю, но это мне не подходит
Аггрегация предполагает что я могу получить интерфейс одного СОМ-объекта через аггрегированный объект, и т.д. А мне этого не нужно. Интерфейсы объектов у меня не должны менятся.
Мне просто нужно чтобы один объект имел доступ к другому, а тот в свою очередь к первому.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[5]: Как правильно реализовать иерархическую структуру объ
Здравствуйте, es3000, Вы писали:
GZ>>В данном случае, ссылки от подчиненных объектов должны подсчитываться у объекта "Фирма". Посмотри что такое аггрегация в COM.
E>Что такое аггрегация знаю, но это мне не подходит E>Аггрегация предполагает что я могу получить интерфейс одного СОМ-объекта через аггрегированный объект, и т.д. А мне этого не нужно. Интерфейсы объектов у меня не должны менятся. E>Мне просто нужно чтобы один объект имел доступ к другому, а тот в свою очередь к первому.
Аггрегирование также предпологает, что ты перенаправляешь все вызововы методов подсчета ссылок родительскому объекту. А это именно то, что тебе нужно. Тебе нужно всего-лишь воспользоваться этим механизмом в том ракурсе в котором требует задача.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: Как правильно реализовать иерархическую структуру объект
Здравствуйте, es3000, Вы писали:
E>Напрмер, есть у меня объект "Фирма", он содержит объект "Отдел", а "Отдел" в свою очередь содержит объект "Сотрудник". E>К объекту "Сотрудник" можно обратиться так: E> Фирма.Отдел.Сотрудник E>А теперь я хочу, чтобы для "Сотрудника" можно было узнать в каком "Отделе" на какой "Фирме" он работает, например: E> лФирма = Сотрудник.Отдел.Фирма E>Если попробовать это реализовать следующим образом:
[skip]
E>То естественно будут циклические ссылки и объект "Фирма" никогда не удалится из памяти:
А в C++ вообще нет подсчёта ссылок, так что всё надо делать ручками — new/delete. Другое дело, что подсчёт ссылок может быть реализован некоторой библиотекой. Тогда люди совершенно правильно писали, что нужно вести подсчёт ссылок на дочерние объекты. Тогда при выходе за пределы зоны видимости Фирма не будет удалена, пока в ней останутся сотрудники. А Сотрудник у себя в деструкторе должен вычёркивать себя из списка сотрудников Фирмы; для этого Сотрудника можно сделать friend class для Фирмы. Ну и дальше включить фантазию/воображение.
Нужно носить в себе еще хаос, чтобы быть в состоянии родить танцующую звезду.
Re[3]: Как правильно реализовать иерархическую структуру объ
Здравствуйте, es3000, Вы писали:
E>Но мне нужно реализовать именно иерархию, объекты "Фирма-Отдел-Сотрудник" я привел только для примера. Так сказать теоретический пример. В реальности я написал несколько программ где есть родительский и вложенный объекты, и всегда приходилось что-то придумывать как удалять такие объекты из памяти.
Опишите реальную задачу. Гипотетический пример может исказить суть задачи. Например, относительно иерархии "Фирма-Отдел-Сотрудник" можно сразу сказать, что она неправильна. Ika хорошо обосновал это в своем сообщении. Поэтому непонятно, как дела обстоят с реальной программой. То ли и там допущена та же самая ошибка, то ли задача заключается в другом.
КЛ>Опишите реальную задачу. Гипотетический пример может исказить суть задачи. Например, относительно иерархии "Фирма-Отдел-Сотрудник" можно сразу сказать, что она неправильна. Ika хорошо обосновал это в своем сообщении. Поэтому непонятно, как дела обстоят с реальной программой. То ли и там допущена та же самая ошибка, то ли задача заключается в другом.
Как раз это и есть реальная задача. Почему же вы считаете задачу неправильной? Ika немного неправильно понял суть задачи. Он пишет: Пример — 100 сотрудников работают в 1 фирме. Объект фирмы будет загружен для каждого сотрудника. А если от сотрудников нужно посмотреть только фамилии, то сколько лишней работы!
А я не собираюсь грузить для каждого сотрудника отдельный объект фирмы. Этим у меня будет заниматься загрузчик. По первому обращению к фирме он создаст объект "Фирма" и всем остальным объектам будет присваивать этот объект. В результате все отделы и все сотрудники будут ссылаться на одну фирму. Но это мы уходим в сторону реализации загрузки по требованию информации.
Сейчас у меня задача правильно реализовать иерархию. В качестве примера могу привести самую простую иерархию, коорая есть почти во всех языках программировани. Это форма и кнопка, которая содержится в этой форме. Я могу через объект формы к кнопке:
Form.AnyButton
и через объект кнопки к форме:
AnyButton.Parent
Я читал статью по СОМ на предмет циклических ссылок, там предлагается самому реализовать механизм "слабых" ссылок. Но и упоминались и другие подходы, которые почему-то ТОЛЬКО упоминались но не осветились подрбно.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: Как правильно реализовать иерархическую структуру объект
Здравствуйте, es3000, Вы писали:
E>Как раз это и есть реальная задача. Почему же вы считаете задачу неправильной?
Только не задачу, а классификацию. Постараюсь пояснить. Какая польза от того, что Фирма содержит Отделы, а Отдел — Сотрудников? Какую функциональную нагрузку несет такая структура? Я не знаю, чем занимается Фирма. Я не знаю, по какому принципу в ней сформированы Отделы. Я не знаю, как эти Отделы взаимодействуют между собой? Допустим, речь идет о софтверной фирме. В ней отдел маркетинга ставит задачи Отделу Разработки и Отделу Качества. Отдел Разработки и Отдел Качества согласовывает свою работу с Отделом маркетинга, а так же посылает спецификацию в Отдел качества и в Отдел Саппорта. Отдел Саппорта посылает жалобы Клиентов в Отдел Маркетинга и в Отдел Разработки. И т.д. Каким образом Вы собираетесь отобразить взаимодействия между Отделами?
Вот и ответ. Архитектура должна строится, исходя из функциональности.
Еще один пример. Теоретически один Сотрудник может работать в нескольких отделах. Или выполнять разные функции, приписанные разным Отделам. Каким образом Вы собрались отобразить эту ситуацию? Кроме того, Сотрудник может перейти из одного отдела в другой. И т.д. И т.п.
КЛ> Я не знаю, чем занимается Фирма. Я не знаю, по какому принципу в ней сформированы Отделы. Я не знаю, как эти Отделы взаимодействуют между собой?
А зачем вам это знать? Зачем вы копаетесь в ненужных деталях? Есть задача, поставленная заказчиком: сделать программу в которой ведется список фирм, список отделов в каждой фирме, и список работников в отделе. Все. Насчет того может ли один работник сразу числиться в нескольких отделах — я не уточнял.
Но предположим что нет. Давайте просто решим ту задачу, о которой я сказал. Другую задачу мне решать не нужно в данный момент. Если надо будет — тогда и буду что-то менять. В любой программе всегда что-то меняется, все предусмотреть невозможно.
Сейчас меня интересует как все-таки решить проблему циклических ссылок в простой иерархической структуре объектов, которую я привел. Что ж тут поделать, встала такая проблема и решить нужно именно эту проблему, а не придумывать как от нее уйти
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[7]: Как правильно реализовать иерархическую структуру объ
Здравствуйте, es3000, Вы писали: E>Сейчас меня интересует как все-таки решить проблему циклических ссылок в простой иерархической структуре объектов, которую я привел. Что ж тут поделать, встала такая проблема и решить нужно именно эту проблему, а не придумывать как от нее уйти.
У меня закралось подозрение, что, возможно, проблему цикличности решить в полном объеме на c++ не удастся. Возможно, я ошибаюсь. Если только самому не писать надстройку к менеджеру памяти, чтоб он ходил и искал оторванные куски связанных объектов. Либо заворачивать каждый ком-объект в некие прокси, назначение которых — только считать ссылки и говорить результат кому-то выше по первому требованию. Но это едва ли входит в scope прикладной программы.
Основная задача — это освобождение памяти при завершении работы программы? Если так, то достаточно помещать каджый полученный экземпляр com-объекта в какое-то глобальное хранилище, а перед завершением программы вызвать у него очистку — чтобы у всех имеющихся объектов были принудительно вызваны DeleteRef до RefCount==0.
Re[2]: Как правильно реализовать иерархическую структуру объ
Здравствуйте, ika, Вы писали:
ika>Пример — 100 сотрудников работают в 1 фирме. Объект фирмы будет загружен для каждого сотрудника. А если от сотрудников нужно посмотреть только фамилии, то сколько лишней работы! Реально тут хватило бы только ID родителя. А если надо — догрузи по нему весь объект и делай с ним что надо.
Ни в коем случае такого допускать нельзя. И, в основном, не с точки зрения производительности, а потому, что в таком случае отслеживание изменений становится просто таки адски сложной задачей. Пользуясь случаем, хочу передать привет GlebZ, а так же настоятельно рекомендую прочесть про Identity Map.
HgLab: Mercurial Server and Repository Management for Windows
Re[7]: Как правильно реализовать иерархическую структуру объ
Здравствуйте, es3000, Вы писали:
E>А зачем вам это знать? Зачем вы копаетесь в ненужных деталях? Есть задача, поставленная заказчиком: сделать программу в которой ведется список фирм, список отделов в каждой фирме, и список работников в отделе. Все. Насчет того может ли один работник сразу числиться в нескольких отделах — я не уточнял.
Прежде чем решать задачу, ее нужно сначала грамотно поставить. (Слово "грамотно" — ключевое. В нем есть смысл.) За всю свою 10-летнюю практику разработки и сопровождения программ я пока еще не встречал Заказчика, который бы сам мог бы грамотно поставить задачу. Он специалист в своем деле. И в программировании может (или даже не должен) разбираться. Для этого он и нанимает специалиста, который знает, как ставятся и решаются подобные задачи. За это и платит деньги.
Неверно поставленная задача приводит к неверному решению. Неверное решение порождает массу проблем, которые, как правило, красиво не решаются, а устраняются путем написания "заплаток". Проблема циклических ссылок — из их числа. "Заплатки" постепенно накапливаются, и, в результате, получается тяжелый и несопровождаемый код.
Несопровождаемым он становится еще и потому, что программист, пишущий программу, не заботится о том, чтобы грамотно поставить задачу. Например, вы не знаете, может ли человек числиться в разных отделах, но, не спросив у Заказчика, предполагаете, что нет. Соответственно, когда выяснится, что ваше предположение неверно, Вам придется ставить "заплатку", а Заказчику — идти на дополнительные расходы. Почему-то мне кажется, что Заказчик платит Вам не за этот "геморрой".
Наконец, Вы не учитываете, как и для чего будет использоваться Ваша программа. Между тем, программа пишется не для того, чтобы просто хранить данные, а для того, чтобы с ними работать. При чем работать определенным образом. Каким? Вы выяснили ответ на этот вопрос? Это важно, т.к. способ хранения и представления данных зависит от того, как эти данные будут в дальнейшем использоваться.
E>Сейчас меня интересует как все-таки решить проблему циклических ссылок в простой иерархической структуре объектов, которую я привел. Что ж тут поделать, встала такая проблема и решить нужно именно эту проблему, а не придумывать как от нее уйти
Проблема циклических ссылок решается очень легко. Она просто не создается.