我有以下问题,我无法完全理解。假设我有一些课程:
TClassA = class
TClassB = class( TClassA )
IMyList = interface( IXList<TClassB> )
TMyList = class( TXList<TClassB>, IMyList )
TMyThing1 = class( TClassB )
TListOfMyThing1 = class( TMyList )
TMyThing2 = class( TClassB )
TListOfMyThing2 = class( TMyList )
TListOfMyThingLists = class( TXList<TMyList> )
基本上,我有一个基础对象(TClassB)和几个派生自它的类。我还有一个包含这些对象的基本列表对象(TMyList)。
每个派生对象都有一个派生自基础容器的容器。
最后,我有一个列表列表,我在其中添加了每个列表。
我们的想法是能够遍历列表列表,然后遍历每个列表并应用所有列表共有的方法:解析,验证,渲染等。
它编译好并运行......直到它关闭,当我得到几个GPF,并且内存转储显示大量的内存泄漏。我想这是在一个继承级别使用接口但不超出该接口的副作用(即,IMyList / TMyList)。
我难倒的地方是如何将接口添加到后两组类中。 TClassB派生自TObject,并且没有接口。我认为我需要的东西(至少是什么样的东西)是这样的:
IMyThing1 = interface( TClassB, IInterface )
TMyThing1 = class( TClassB, TInterfacedObject, IMyThing1 )
但这不合法! (这是多重继承。坏了!)
如果我只是使用从TClassB派生的合法资料:
IMyThing1 = interface( TClassB, IInterface )
TMyThing1 = class( TClassB, IMyThing1 )
编译器(DXE5)抱怨:
[dcc32 Error] x.pas(#): E2291 Missing implementation of interface method IInterface.QueryInterface
[dcc32 Error] x.pas(#): E2291 Missing implementation of interface method IInterface._AddRef
[dcc32 Error] x.pas(#): E2291 Missing implementation of interface method IInterface._Release
虽然在某处的杂草中#线已关闭。 (IOW,它实际上并没有告诉我错误的位置。我只能通过选择性地注释掉代码来确定。)
是否有必要为从非接口类派生的每个类显式实现这些接口函数,以便保持&#34;托管&#34;被管理错误的对象&#34;?
或许还有另一种方法不那么明显?
(这似乎是一个问题,主要是因为Borland-Inprise-CG-EMBT的人们对实施&#34;真正的&#34;多重继承有着基本的宗教反对意见,因为愚蠢的人可以用它做蠢事。 。)
顺便说一句,这只是为了让自动引用计数(ARC)添加到类中而进行的 LOT !
注意:这可能是之前已经回答的问题,但我不知道如何对问题进行说明以使其显示在搜索中。
答案 0 :(得分:3)
混合接口和非接口对象指针并不是一个好主意,特别是如果从非接口对象指针中检索接口。如果使用接口,则应该为所有内容使用接口,包括变量和内部容器。话虽这么说,为了使这段代码在不崩溃的情况下工作,您可能必须覆盖_AddRef()
和_Release()
来禁用对实现接口的类的引用计数。例如,TComponent
就是这样做的。
答案 1 :(得分:1)
另一个选择是自己实现缺少的方法,以便满足编译器。这里有一篇很棒的文章,详细信息如下:https://sergworks.wordpress.com/2010/11/24/delphi-interfaces-without-reference-counting/
或者,或许更好的是,只是继承自TSingletonImplementation - 它为您实现了所需的方法。
答案 2 :(得分:0)
我发现了一个派生自TClassA的类,它是一个TInterfacedClassA,我从中派生出了TClassB。
TInterfacedClassA = class
TClassB = class( TInterfacedClassA )
其余的,我这样做了:
IMyList = interface( IXList<TClassB> )
TMyList = class( TXList<TClassB>, IMyList )
IMyThing1 = interface( IInterface )
TMyThing1 = class( TClassB, IInterface )
IListOfMyThing1 = interface( IInterface )
TListOfMyThing1 = class( TMyList, IListOfMyThing1 )
IMyThing2 = interface( IInterface )
TMyThing2 = class( TClassB, IInterface )
IListOfMyThing2 = interface( IInterface )
TListOfMyThing2 = class( TMyList, IListOfMyThing2 )
TListOfMyThingLists = class( TXList<TMyList> )
类中的所有setter和getter都被更改为使用Ixxx类型而不是使用它们的Txxx类型,并且方法也被更改为传递并返回Ixxx类型而不是Txxx类型。
这是有效的,除了添加列表之外,我需要这样做:
TListOfMyThing1.Add( aItem : IMyThing1 ) : integer;
begin
Result := inherited Add( aItem as TClassB );
end;
这对我来说似乎很奇怪,因为aItem实际上是从TClassB派生的。
也许我需要一个IClassB来代替IInterface派生其他接口?