接口“递归”和参考计数 [英] Interface "recursion" and reference counting

查看:193
本文介绍了接口“递归”和参考计数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个小问题的接口。这里是伪代码:

  type 
Interface1 = interface
end;

Interface2 = interface
end;

TParentClass = class(TInterfacedObject,Interface1)
private
fChild:Interface2;
public
procedure AddChild(aChild:Interface2);
结束

TChildClass = class(TInterfacedObject,Interface2)
private
fParent:Interface2;
public
构造函数创建(aPArent:Interface1);
结束

任何人都可以看到缺陷?我需要孩子参考它的父母,但引用计数在这种情况下不起作用。如果我创建一个ParentClass实例,并添加一个子代,则父类永远不会被释放。我可以明白为什么

解决方案

引用计数引用有两个语义:它作为所有权的一部分作为浏览对象图的一种手段。



通常,在一个循环中的所有链接中,您不需要这些语义参考图。也许只有父母自己的孩子,而不是相反呢?如果是这种情况,您可以通过将孩子的引用存储为指针,使其成为父级弱链接,如下所示:

  TChildClass = class(TInterfacedObject,Interface2)
private
fParent:Pointer;
函数GetParent:Interface1;
public
构造函数创建(aPArent:Interface1);
属性Parent:Interface1读取GetParent;
结束

函数TChildClass.GetParent:Interface1;
begin
结果:= Interface1(fParent);
结束

构造函数TChildClass.Create(AParent:Interface1);
begin
fParent:=指针(AParent);
结束

如果实例树的根保证在某个地方保持活动,那么这是安全的,即你不依赖于仅保留对树的分支的引用,并且仍然能够导航整个树。


I have a small problem with interfaces. Here it is in Pseudo code :

type
  Interface1 = interface
  end;

  Interface2 = interface
  end;

  TParentClass = class(TInterfacedObject, Interface1)
  private
    fChild : Interface2;
  public
    procedure AddChild(aChild : Interface2);
  end;

  TChildClass = class(TInterfacedObject, Interface2)
  private
    fParent : Interface2;
  public
    constructor Create(aPArent : Interface1);
  end;

Can anyone see the flaw? I need the child to have a reference to it's parent, but the reference counting doesn't work in this situation. If I create a ParentClass instance, and add a child, then the parent class is never released. I can see why. How do I get round it?

解决方案

A reference-counted reference has two semantics: it acts as a share of ownership as well as a means of navigating the object graph.

Typically, you don't need both of these semantics on all links in a cycle in the graph of references. Perhaps only parents own children, and not the other way around? If that is the case, you can make the child references to the parent weak links, by storing them as pointers, like this:

TChildClass = class(TInterfacedObject, Interface2)
private
  fParent : Pointer;
  function GetParent: Interface1;
public
  constructor Create(aPArent : Interface1);
  property Parent: Interface1 read GetParent;
end;

function TChildClass.GetParent: Interface1;
begin
  Result := Interface1(fParent);
end;

constructor TChildClass.Create(AParent: Interface1);
begin
  fParent := Pointer(AParent);
end;

This is safe if the root of the tree of instances is guaranteed to be kept alive somewhere, i.e. you are not relying on only keeping a reference to a branch of the tree and still being able to navigate the whole of it.

这篇关于接口“递归”和参考计数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆