4

在手动内存分配和指针仍然占主导地位的世界中(Borland Delphi),我需要一个通用的解决方案来解决我认为的普遍问题:

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

4

4 回答 4

3

如果您想通知其他人更改,您应该实施“观察者模式”。Delphi 已经为您为 TComponent 后代完成了这项工作。您可以调用 TComponent.FreeNotification 方法并在其他组件被销毁时通知您的对象。它通过调用 Notification 方法来实现。您可以通过调用 TComponent.RemoveFreeNotification 将自己从通知列表中删除。另请参阅此页面

大多数垃圾收集器不会让您获得参考列表,因此在这种情况下它们不会提供帮助。如果您使用接口,Delphi 可以进行引用计数,但是您需要自己跟踪引用。

于 2008-08-20T18:18:02.273 回答
1

我不太明白你为什么要这样做。您肯定会在使用之前检查 not Nil 中的引用吗?

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

  1. 让对象管理器拥有自己的引用计数。
  2. 创建一个引用计数管理器类。

我可能会将 AddRef() 和 ReleaseRef() 函数添加到管理器或引用感知类。然后,您可以使用这些来检查在任何时候存在多少引用。COM 就是这样做的。

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

于 2008-08-20T14:56:44.897 回答
0

您是在尝试跟踪谁在引用对象,以便在对象被销毁时清除这些引用,还是在尝试跟踪何时可以安全地销毁对象?

如果是后者,那么听起来您正在寻找垃圾收集器。我从未与 Delphi 打过交道,所以我不知道您是否可以使用 GC,但如果没有,我会感到惊讶。

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

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

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

于 2008-08-20T15:02:30.170 回答
0

你想要这个有特定的原因吗?您是否遇到了流氓指针的问题,或者您认为有一天它可能会成为问题?

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

关于模式的一些信息:

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

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

于 2008-11-06T08:42:31.837 回答