如何跟踪对象的引用?

时间:2008-08-20 14:39:13

标签: oop delphi

在一个手动内存分配和指针仍然统治的世界(Borland Delphi),我需要一个通用的解决方案,我认为这是一个普遍的问题:

在给定时刻,可以从多个位置(列表,其他对象,......)引用对象。是否有一种很好的方法来跟踪所有这些引用,以便在对象被销毁时我可以更新它们?

4 个答案:

答案 0 :(得分:3)

如果您想要通知其他人更改,您应该实施"Observer Pattern"。 Delphi已经为你为TComponent后代做了这个。您可以调用TComponent.FreeNotification方法,并在其他组件被销毁时通知您的对象。它通过调用Notification方法来实现。您可以通过调用TComponent.RemoveFreeNotification从通知列表中删除自己。另请参阅this page

大多数垃圾收集器都不允许您获取引用列表,因此在这种情况下它们无济于事。如果您使用接口,Delphi可以进行引用计数,但是您需要自己跟踪引用。

答案 1 :(得分:1)

我无法弄清楚你为什么要这样做。当然你在使用之前只检查一个非Nil的参考?

Anwyays,我会考虑两种可能的解决方案:

  1. 让对象管理员自己引用计数。
  2. 创建引用计数管理器类。
  3. 我可能会将AddRef()和ReleaseRef()函数添加到管理器或引用感知类中。然后,您可以使用它们来检查任何点上存在多少引用。 COM这样做。

    引用感知类只管理它自己的引用计数。管理器可以使用Map将指针与一个整数相关联以进行计数。

答案 2 :(得分:0)

您是否正在尝试跟踪谁引用某个对象,以便您可以在对象被销毁时清除这些引用,或者您是否想要跟踪何时可以安全地销毁该对象?

如果是后者,那么听起来你正在寻找一个垃圾收集器。我从来没有处理过德尔福,所以我不知道你是否可以使用它,但如果没有,我会感到惊讶。

如果前者那么GC可能无济于事。如果Delphi支持OOP / inheritence(我老实说不知道是否这样做)你可以做这样的事情(伪代码):

// 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())然后该对象向集合发出信号,表明它正在被销毁,因此集合可以做任何需要的事情。

不幸的是,如果你想使用内置集合,这不是一个很好的解决方案。你必须编写自己的集合对象(它们可以只包装内置的对象)。并且需要确保您在任何想要跟踪对象的地方注册。这不是我认为的“快乐”解决方案,但对于小型项目来说,它可能不会太糟糕。我主要希望这个想法能够帮助产生其他想法。 :)

答案 3 :(得分:0)

你想要这个特定原因吗?您是否遇到过流氓指针的问题,或者您认为某天可能会出现问题?

恕我直言,如果你正确设计你的应用程序就不会有问题,并且使用适当的模式确实对你有帮助。

有关模式的一些信息:

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

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