Вопрос

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

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

Это было полезно?

Решение

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

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

Другие советы

Я не совсем понимаю, зачем тебе понадобилось это делать.Конечно, вы бы просто проверили ссылку на not Nil, прежде чем использовать ее?

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

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

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

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

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

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top