一个关于接口的问题 ( 积分: 100 )

  • 主题发起人 wk_knife
  • 开始时间
W

wk_knife

Unregistered / Unconfirmed
GUEST, unregistred user!
能否建立一个接口的TLIST,一旦接口的记树为0,就自动从LIST中删除该接口。
应该用到NOTIFY吧?
是否需要修改默认的记数函数?
 
能否建立一个接口的TLIST,一旦接口的记树为0,就自动从LIST中删除该接口。
应该用到NOTIFY吧?
是否需要修改默认的记数函数?
 
Delphi中有一个TInterfaceList,你可以看看它的源码.
 
那个不能自动删除Item
 
你这样作的目的是什么呢?
用接口的一个目的就是不用维护对象的生存期,由接口来维护对象的实例。
接口本身没有实例的,好像不能计数吧。
 
[ 一旦接口的记树为0,就自动从LIST中删除该接口 ]
只要你保存了接口,那么其实你也占用了一个接口计数.
如果是你自己的接口实现类,那么最好是能够在必要的时候通知你的List
默认情况下的实现.Addref()返回的值是refCount++的结果值.实在不行,你可以尝试定时查询.
var
iRefCount;
begin
iRefCount = pIntf.Addref();
pIntf.Release();
if iRefCount = 2 then
begin
//接口计数只剩下了你的一个
end;
 
只是突然有了这么一个想法。
我给我的类添加了一个被别的类引用的记数,在恰当的时候(比方“保存”文档的操作)删除记数为零的这个类的实例。
做一个画图程序,如果把画笔等类加到图元里,图元类就太占地方了,所以把画笔、画刷之类的类作成带记数的,共享一下。节约内存。
不知道诸位是否有更好的设计
 
我觉得用接口就可以。定义画笔、画刷的接口,由接口来维护画笔、画刷实例引用。
 
z真厉害
 
我知道如何做个类似的接口了。[:D]
在TLIST里保存接口的指针就可以了。
PInterface=^TInterface;
这样保存到TLIST里并不会导致引用记数的增加。[:D]
 
bluesaga,仔细再说一下你的想法?[:)]
 
"做一个画图程序,如果把画笔等类加到图元里,图元类就太占地方了,所以把画笔、画刷之类的类作成带记数的,共享一下。节约内存。"
这个是不是可以考虑单例来实现?
我不太懂画图,但是我觉得你设计的这些类都应该是无状态的,只是些操作,因此只要有一个实例就可以了
 
能完全把图元类作成无状态类最好,不过我现在还没办法和时间这样做,只能做成部分的,象FLYWEIGHT
 
实现notify通知机制是相对比较合理的。
所有的东西都使用接口来声明,相对而言是比较难于驾驭的,因为这需要你在最开始就涉及好架构和接口。
你的图元的东西,这个我觉得有些问题。接口计数主要是用来实现声明周期管理的,似乎涉及不到节约内存。
OO内存占用分两种,1.代码占用空间2.对象实例占用空间。不要看TBrush/TPen/TCanvas等等类的方法很多,那个是占用的代码内存,基本上你是销不掉的。而对象实例所占用的内存基本上是这个实例的字段的多少。这些图元类相对属于比较简单的类,实力字段并没有多少的。
 
我是这样考虑的:
比方我有一个通用的接口IPen,实现IPen的假设是TPen类。
图元设计的时候你可以这样设计
TGObject=class(TInterfacedObject,IPen)
private
FPen:TPen;
end;

constructor create(......);
begin
FPen:=TPen.create;
end;

这种方式,每个图元类就都会创建一个TPEN实例。相对于下面的方式
constructor create(......);
begin
SetPen(SystemCurrentPen);//FPEN是一个对程序中当前画笔的引用
end;

肯定要多占一些内存。
程序中可用的现有的画笔实例,包括SystemCurrentPen,我希望用一个列表来管理。当发现没有图元实例引用某个画笔实例时,就释放这个画笔实例,因为接口是生命期自动管理的,所以有上面的一问。

bluesaga说把图元设计成无状态类,但我觉得不同类型的图元的处理方法很不一样,设计成无状态类,可能这个无状态类中就要容纳对各种不同类型图元的处理,也很麻烦,当然可以为每一类图元设计一个无状态类,但这样对图元的管理又添了麻烦。
想来想去,总是麻烦,需要高人点拨。
高人们,该出手时就出手吧。
 
TGObject=class(TInterfacedObject,IPen)
private
FYourPen:IPen;
property
IYourPen:IPen read FYourPen write FYourPen;
end;
面向对象讲多用聚合,你可以把实现好的接口传给TGObject
 
多人接受答案了。
 
顶部