在一个手动内存分配和指针仍然统治的世界(Borland Delphi),我需要一个通用的解决方案,我认为这是一个普遍的问题:
在给定时刻,可以从多个位置(列表,其他对象,......)引用对象。是否有一种很好的方法来跟踪所有这些引用,以便在对象被销毁时我可以更新它们?
答案 0 :(得分:3)
如果您想要通知其他人更改,您应该实施"Observer Pattern"。 Delphi已经为你为TComponent后代做了这个。您可以调用TComponent.FreeNotification方法,并在其他组件被销毁时通知您的对象。它通过调用Notification方法来实现。您可以通过调用TComponent.RemoveFreeNotification从通知列表中删除自己。另请参阅this page。
大多数垃圾收集器都不允许您获取引用列表,因此在这种情况下它们无济于事。如果您使用接口,Delphi可以进行引用计数,但是您需要自己跟踪引用。
答案 1 :(得分:1)
我无法弄清楚你为什么要这样做。当然你在使用之前只检查一个非Nil的参考?
Anwyays,我会考虑两种可能的解决方案:
我可能会将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)
你想要这个特定原因吗?您是否遇到过流氓指针的问题,或者您认为某天可能会出现问题?
恕我直言,如果你正确设计你的应用程序就不会有问题,并且使用适当的模式确实对你有帮助。
有关模式的一些信息: