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

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

有帮助吗?

解决方案

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

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

其他提示

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

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

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

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

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

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

如果是后者,那么听起来您正在寻找垃圾收集器。我从来没有接触过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() ),那么对象会向集合发出信号,表明它正在被销毁,以便集合可以执行它需要的任何操作。

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

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

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

关于模式的一些信息:

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top