Как отслеживать ссылки на объект? - PullRequest
3 голосов
/ 20 августа 2008

В мире, где ручное распределение памяти и указатели по-прежнему правят (Borland Delphi), мне нужно общее решение для общей проблемы:

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

Ответы [ 4 ]

3 голосов
/ 20 августа 2008

Если вы хотите уведомить других об изменениях, вам следует реализовать «Шаблон наблюдателя» . Delphi уже сделала это для вас, потомков TComponent. Вы можете вызвать метод TComponent.FreeNotification и уведомить свой объект об уничтожении другого компонента. Это делается путем вызова метода уведомления. Вы можете удалить себя из списка уведомлений, вызвав TComponent.RemoveFreeNotification. Также смотрите эту страницу .

Большинство сборщиков мусора не позволяют получить список ссылок, поэтому они не помогут в этом случае. Delphi может выполнять подсчет ссылок, если вы будете использовать интерфейсы, но опять же вам нужно самим отслеживать ссылки.

1 голос
/ 20 августа 2008

Я не могу понять, почему вы хотите это сделать. Наверняка вы бы просто проверили ссылку в Nil перед ее использованием?

Anwyays, я бы рассмотрел два возможных решения:

  1. У менеджера объектов есть свои собственные счетчики ссылок.
  2. Создание класса менеджера подсчета ссылок.

Я бы, вероятно, добавил бы функции AddRef () и ReleaseRef () либо к менеджеру, либо к справочному классу. Затем вы можете использовать их, чтобы проверить, сколько ссылок существует в любой точке. COM делает это таким образом.

Класс, поддерживающий ссылки, будет управлять только собственным счетчиком ссылок. Менеджер может использовать карту, чтобы связать указатели с целым числом для подсчета.

0 голосов
/ 06 ноября 2008

Есть ли конкретная причина, по которой вы хотите этого? У вас проблемы с указателями мошенников, или вы думаете, что однажды это может стать проблемой?

ИМХО, это не будет проблемой, если вы правильно разработали свое приложение, и использование соответствующих шаблонов действительно вам поможет.

Некоторая информация о скороговорках:

http://delphi.about.com/od/oopindelphi/a/aa010201a.htm

http://www.obsof.com/delphi_tips/pattern.html

0 голосов
/ 20 августа 2008

Вы пытаетесь отслеживать, кто ссылается на объект, чтобы вы могли очистить эти ссылки, когда объект уничтожен, или вы пытаетесь отслеживать, когда безопасно уничтожить объект?

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

Если первый, то GC, вероятно, не поможет. Если Delphi поддерживает ООП / наследование (честно говоря, я не знаю, так ли это), вы можете сделать что-то вроде этого (псевдокод):

// Anything that will use one of your tracked objects implements this interface
interface ITrackedObjectUser {
  public void objectDestroyed(TrackedObject o);
}

// All objects you want to track extends this class
class TrackedObject {
  private List<ITrackedObjectUser> users;

  public void registerRef(ITrackedObjectUser u) {
    users.add(u);
  }

  public void destroy() {
    foreach(ITrackedObjectUser u in users) {
      u.objectDestroyed(this);
    }
  }
}

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

К сожалению, это не очень хорошее решение, если вы хотите использовать встроенные коллекции. Вы должны написать свои собственные объекты коллекции (они могут просто обернуть встроенные объекты). И для этого потребуется убедиться, что вы регистрируетесь везде, где хотите отслеживать объект. Это не то, что я бы назвал «счастливым» решением, хотя для небольших проектов это, вероятно, не было бы слишком плохо. Я в основном надеюсь, что эта идея поможет породить другие идеи. :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...