Пожалуйто, посоветуйте решение...
От: Jack Украина http://tr.dn.ua/~dionis/
Дата: 15.01.03 22:44
Оценка:
Поразмыслив, я решил сделать у себя подсчет ссылок в точности как в COM. Теоретически, все получалось красиво. В скриптовом языке, например, можно отказаться от оператора delete, как в c#. Для этого достаточно сделать в cVariant в соответствующих местах AddRef и Release. Но возникает одна пробелам. Если, вдруг, пользователю придет в голову написать в методе(в скриптовом языке) следующее:
this.test=this;
Тогда в объекте будет динамически создана переменная, указатель на самого себя, которая, в свою очередь будет иметь ссылку на объект. Такой объект, фактически, нельзя будет удалить. Раньше, для сборки мусора я использовал(и, в приницпе, не собирался отказываться) коллекцию(в приложении) указателей на все объекты в системе(наследники iBase аналог IUnkown)(в диструкторе они оттуда удалялись), и в момент удаления приложения, в случае, если в этой коллекции были объекты, они удалялись. Теперь этот метод работать не будет, так как даже если я, с горя, буду делать Release пока количество ссылок не станет равно 0(имеется ввиду в деструкторе приложения), то когда объект будет удаляться, удалиться и cVariant который хранит указатель на объект и снова попытается удалить этот объект.
В принципе, так как это будет происходить в диструкторе то можно просто сделать проверку на количество ссылок меньшее 0, то ничего не делать.
Это не красиво, но мелочь. Если поступать таким образом, то может возникнуть другая проблема. Ведь одновременно с этим, где нибудь еще может оказаться указатель на этот объект и уже после его удаления оного, снова попытается делать Release для существующего объекта. Частично эту проблему можно решить, при помощи функции IsValid(iBase*) которая проверяется в коллекции приложения существует ли переданный указатель. Но в таком случае придется делать такую проверку при каждом Release, что может сильно понизить производительность. В общем, пока красивых решений в голову не приходит. Может что ни будь посоветуете?
Искренне Ваш, Джек.
Re: Пожалуйто, посоветуйте решение...
От: Багер  
Дата: 16.01.03 02:39
Оценка:
Здравствуйте, Jack, Вы писали:

J>this.test=this;

J>Тогда в объекте будет динамически создана переменная, указатель на самого себя,
А факт создания замечен не будет? Это как? Конструктора нет?
Ваша программа работает корректно? Один звонок и я всё исправлю!

Делаю потенциальные фичи :))
Re: Пожалуйто, посоветуйте решение...
От: m.a.g. Мальта http://dottedmag.net/
Дата: 16.01.03 04:54
Оценка: 2 (1)
Здравствуйте, Jack, Вы писали:

J>this.test=this;


Это общая проблема подсчета ссылок — он не работает для циклических структур. В COM от этого избавляются специальными методами, например, вырисовывая дерево объектов и вручную считая, где нужно увеличивать/уменьшать счетчик ссылок, а где нет или используя промежуточные компоненты для разрыва циклов.
... << Metallica [Best ballads] Nothing else matters >> ...
Re[2]: Пожалуйто, посоветуйте решение...
От: Jack Украина http://tr.dn.ua/~dionis/
Дата: 16.01.03 08:33
Оценка:
Здравствуйте, Багер, Вы писали:

Б>Здравствуйте, Jack, Вы писали:


J>>this.test=this;

J>>Тогда в объекте будет динамически создана переменная, указатель на самого себя,
Б>А факт создания замечен не будет? Это как? Конструктора нет?
Как такового нет. Но единственные точки входа для чтения-записи-объявления перемнной. Допустим я способен отследить циклический уазатель. Что мне с этим делать? Создавать его удалив заранее одну ссылку? Тогда что сделать по уничтожению переменной?
Искренне Ваш, Джек.
Re: Пожалуйто, посоветуйте решение...
От: Sm0ke Россия ksi
Дата: 18.07.06 12:13
Оценка:
Здравствуйте, Jack, Вы писали:

В ref хранить указатель на контейнер рефа и при присвоении рефа на объект проверять указатили в родительских контейнерах.

class object
{
protected:
  ulong num_refs;
public:
  object * add_ref();
  void release();
};

class ref
{
protected:
  object * h_obj;
  object * h_container;
  void set(object * h_new_obj);
  void release();
};

void ref::set(object * h_new_obj)
{
  if (h_new_obj == h_container) return;
  this->release();
  this->h_obj= h_new_obj->add_ref();
}


сюда конечно ещё конструктор нужен и т.д.
Re[2]: Пожалуйто, посоветуйте решение...
От: Кодт Россия  
Дата: 18.07.06 12:56
Оценка:
Здравствуйте, m.a.g., Вы писали:

MAG>Это общая проблема подсчета ссылок — он не работает для циклических структур. В COM от этого избавляются специальными методами, например, вырисовывая дерево объектов и вручную считая, где нужно увеличивать/уменьшать счетчик ссылок, а где нет или используя промежуточные компоненты для разрыва циклов.


А в boost::shared_ptr для этих же целей используют weak_ptr
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Перекуём баги на фичи!
Re[2]: Пожалуйто, посоветуйте решение...
От: HiSH Россия http://m0riarty.ya.ru
Дата: 18.07.06 14:21
Оценка:
Здравствуйте, Sm0ke, Вы писали:

S>Здравствуйте, Jack, Вы писали:


S>В ref хранить указатель на контейнер рефа и при присвоении рефа на объект проверять указатили в родительских контейнерах.


S>сюда конечно ещё конструктор нужен и т.д.


А как быть с цепочками, длина которых больше 1?
Re: Пожалуйто, посоветуйте решение...
От: Константин Л. Франция  
Дата: 18.07.06 15:04
Оценка:
Здравствуйте, Jack, Вы писали:

посмотри, как сделан GC в .NET
Тут, кстати, пробегали ссылки на реализации GC для с++, воспользуйся поиском
Re: Пожалуйто, посоветуйте решение...
От: Аноним  
Дата: 18.07.06 17:09
Оценка:
Здравствуйте, Jack, Вы писали:

[]

В питоне (www.python.org) сборщик мусора умеет убирать циклы (при соблюдении определенных условий). Исходники открыты.
Re[3]: Пожалуйто, посоветуйте решение...
От: Sm0ke Россия ksi
Дата: 19.07.06 09:34
Оценка:
Здравствуйте, HiSH, Вы писали:

HSH>А как быть с цепочками, длина которых больше 1?


Неужели в объекте придётся хранить список рефов, которые на него указывают?

class ref;

class object
{
protected:
  ulong num_refs;
  list<ref *> lst_refs;
public:
  object * add_ref(ref * h_ref);
  void release(ref * h_ref);
};


Но эта схема намного медленнее будет...
Re[4]: Пожалуйто, посоветуйте решение...
От: Максим Зелинский  
Дата: 19.07.06 15:10
Оценка:
Здравствуйте, Sm0ke, Вы писали:

S>Здравствуйте, HiSH, Вы писали:


HSH>>А как быть с цепочками, длина которых больше 1?


S>Неужели в объекте придётся хранить список рефов, которые на него указывают?


S>
S>class ref;

S>class object
S>{
S>protected:
S>  ulong num_refs;
S>  list<ref *> lst_refs;
S>public:
S>  object * add_ref(ref * h_ref);
S>  void release(ref * h_ref);
S>};
S>


S>Но эта схема намного медленнее будет...

Еще бы, подсчет ссылок — это самое быстрое решение. Но оно тут же начинает буксовать, когда возникают циклические ссылки. Все другие решения, которые автоматически разрывают цикличность — дороже. Так что либо скорость, либо удобство. Больше никак.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.