Как реализовать объекты с подсчетом ссылок в Delphi - PullRequest
1 голос
/ 28 января 2009

У меня есть графоподобная структура. Я не знаю точно, когда уничтожать объекты традиционным способом Delphi, вместо этого я хотел бы реализовать что-то вроде объектов с подсчетом ссылок. Я знаю, что могу использовать что-то вроде object.GetReference и object.Release вместо Free и использовать приватную переменную для подсчета ссылок, но есть ли лучший способ?

Спасибо

Ответы [ 4 ]

15 голосов
/ 28 января 2009

Если у вас возникли проблемы с определением правильного способа (места, порядка и т. Д.) Уничтожения стандартных объектов в программе на Delphi, то использование объектов или интерфейсов с подсчетом ссылок не поможет вам вообще.

Я понимаю, что вы хотите, чтобы узлы на графике сохраняли ссылки друг на друга, и когда не осталось ссылок на объект, он должен быть уничтожен автоматически. Но учтите тот факт, что каждый из двух узлов может иметь ссылку на другой узел, и количество ссылок никогда не достигнет 0 снова, поэтому эти объекты никогда не будут освобождены. Вам нужно будет разорвать хотя бы одну из ссылок / зависимостей вручную. И если вам все равно придется это делать, то вы можете вообще пропустить подсчет ссылок. Для получения дополнительной информации см. Статью в Википедии о слабых ссылках . Интерфейсы могут использоваться в Delphi для подсчета ссылок, но слабые ссылки могут поддерживаться только при умном приведении типов. Для примера см. этот исходный код и его комментарии .

Одна идея, которую вы, возможно, захотите изучить, - это сохранить стандартное управление временем жизни ваших объектов и позволить графическим объектам отслеживать зависимости.

Пусть у каждого графического объекта есть список других объектов, с которыми он связан. Теперь вы можете просто освободить любой из объектов, и служебный код для списка удалит все ссылки на уничтожаемый объект из всех других объектов. Если вы хотите изменить график, вы просто освобождаете узлы, которые хотите удалить, и зависимости будут обновлены. Если вы хотите уничтожить весь граф, просто уничтожьте все узлы. В основном у вас есть список узлов (владение, управление временем жизни) и другая структура данных для описания графа.

3 голосов
/ 28 января 2009

Вы можете использовать интерфейсы вместо объектов, нижележащие объекты будут автоматически подсчитываться, и самое лучшее, что delphi уничтожит объекты для вас, когда refcount = 0.

2 голосов
/ 28 января 2009

Если вы используете D2009, вы можете использовать реализацию интеллектуальных указателей Барри Келли.

http://barrkel.blogspot.com/2008/11/somewhat-more-efficient-smart-pointers.html

В противном случае использование интерфейсов - ваш лучший выбор. Создайте интерфейс со ВСЕМИ необходимыми вам функциями, создайте объект, который реализует этот интерфейс и происходит от TInterfacedObject, а затем используйте интерфейсы везде, а не объект.

2 голосов
/ 28 января 2009

Как вы, наверное, знаете, в Delphi нет сборщика мусора.

Лучше всего, чтобы ваши объекты происходили из TInterfacedObject. Что-то вроде

type
  IMyObject = interface
    [Guid]
  end;

  MyObject = class(IMyObject, TInterfacedObject)
  end;

var
  myObject: IMyObject;
begin
  myObject := TMyObject.Create;
end

Переменная myObject рассчитана по ссылкам и будет освобождена, когда ее счетчик ссылок уменьшится до нуля.

...