Как отслеживать ссылки на объект?

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

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

20.08.2008 14:39:12
4 ОТВЕТА
РЕШЕНИЕ

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

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

3
20.08.2008 18:18:02

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

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

  1. У управляющих объектами свои собственные счетчики ссылок.
  2. Создайте класс менеджера подсчета ссылок.

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

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

1
20.08.2008 14:56:44
+1 за вторую идею, создание подкласса TInterfacedObject (или создание корневого класса, похожего на него) было бы простым способом создания класса менеджера refcount
mjn 10.11.2010 06:59:17

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

Если последнее, то звучит так, будто вы ищете сборщика мусора. Я никогда не имел дело с 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 () в деструкторе объекта), тогда объект сообщает коллекции, что он уничтожается, поэтому коллекция может делать все, что ей нужно.

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

0
20.08.2008 15:02:30

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

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

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

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

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

0
6.11.2008 08:42:31