Gry*_*ffe 13 delphi interface delphi-2007 implements
我希望引用计数应该在接口实现中的外部聚合对象上工作.如果我可以参考另一个例子:实现多个接口的类中的清晰度(替代委托):
这是行为的最小再现:
program SO16210993;
{$APPTYPE CONSOLE}
type
IFoo = interface
procedure Foo;
end;
TFooImpl = class(TInterfacedObject, IFoo)
procedure Foo;
end;
TContainer = class(TInterfacedObject, IFoo)
private
FFoo: IFoo;
public
constructor Create;
destructor Destroy; override;
property Foo: IFoo read FFoo implements IFoo;
end;
procedure TFooImpl.Foo;
begin
Writeln('TFooImpl.Foo called');
end;
constructor TContainer.Create;
begin
inherited;
FFoo := TFooImpl.Create;
end;
destructor TContainer.Destroy;
begin
Writeln('TContainer.Destroy called');//this line never runs
inherited;
end;
procedure Main;
var
Foo : IFoo;
begin
Foo := TContainer.Create;
Foo.Foo;
end;
begin
Main;
Readln;
end.
Run Code Online (Sandbox Code Playgroud)
如果不是使用implements
,我在TImplementor
类中实现接口,然后运行析构函数.
Dav*_*nan 15
这里发生的是你调用TContainer.Create
并创建一个对象的实例.但是,然后将该实例分配给接口引用,即全局变量Foo
.因为该变量是类型IFoo
,所以接口委托意味着实现对象是实例,TFooImpl
而不是实例TContainer
.
因此,没有任何东西可以引用它的实例TContainer
,它的引用计数永远不会增加,因此它永远不会被破坏.
我不认为这有一个非常简单的方法.您可以使用,TAggregatedObject
但它可能无法解决您的问题.它会迫使你声明TContainer.FFoo
为类型的TFooImpl
,我想你不想做的事.无论如何,这就是重新演绎的方式:
program SO16210993_TAggregatedObject;
{$APPTYPE CONSOLE}
type
IFoo = interface
procedure Foo;
end;
TFooImpl = class(TAggregatedObject, IFoo)
procedure Foo;
end;
TContainer = class(TInterfacedObject, IFoo)
private
FFoo: TFooImpl;
function GetFoo: IFoo;
public
destructor Destroy; override;
property Foo: IFoo read GetFoo implements IFoo;
end;
procedure TFooImpl.Foo;
begin
Writeln('TFooImpl.Foo called');
end;
destructor TContainer.Destroy;
begin
Writeln('TContainer.Destroy called');//this line does run
FFoo.Free;
inherited;
end;
function TContainer.GetFoo: IFoo;
begin
if not Assigned(FFoo) then
FFoo := TFooImpl.Create(Self);
Result := FFoo;
end;
procedure Main;
var
Foo : IFoo;
begin
Foo := TContainer.Create;
Foo.Foo;
end;
begin
Main;
Readln;
end.
Run Code Online (Sandbox Code Playgroud)
该文档不谈论这个:
用于实现委托接口的类应该派生自TAggregationObject.
最初我找不到任何相关的文档TAggregationObject
.最后我意识到它实际上已经命名TAggregatedObject
并且有记录.
TAggregatedObject通过实现委托给控制IInterface的IInterface方法为聚合的内部对象提供功能.
聚合对象是由多个接口对象组成的对象.每个对象都实现自己的行为和接口,但所有对象共享相同的引用计数,即控制器对象的引用计数.在容器模式中,控制器是容器对象.
TAggregatedObject本身不支持任何接口.但是,正如聚合的典型情况一样,它确实实现了IInterface的方法,这些方法由从它下降的对象使用.因此,TAggregatedObject充当实现用于创建作为聚合的一部分的对象的接口的类的基础.
TAggregatedObject用作创建包含对象和连接对象的类的基础.使用TAggregatedObject可确保对IInterface方法的调用委托给聚合的控制IInterface.
控制IInterface在TAggregatedObject的构造函数中指定,并由Controller属性指示.
另外还有来自源代码的评论:
TAggregatedObject和TContainedObject是用于聚合或包含在外部控制对象中的接口对象的合适基类.在外部对象类声明中的接口属性上使用"implements"语法时,请使用这些类型来实现内部对象.
由聚合对象代表控制器实现的接口不应与控制器提供的其他接口区分开.聚合对象不得维护自己的引用计数 - 它们必须与其控制器具有相同的生命周期.为此,聚合对象将引用计数方法反映到控制器.
TAggregatedObject只是将QueryInterface调用反映到其控制器.从这样的聚合对象,可以获得控制器支持的任何接口,并且只能获得控制器支持的接口.这对于实现使用一个或多个内部对象来实现在控制器类上声明的接口的控制器类非常有用.聚合促进跨对象层次结构的实现共享.
TAggregatedObject是大多数聚合对象应该继承的内容,尤其是在与"implements"语法结合使用时.
归档时间: |
|
查看次数: |
9011 次 |
最近记录: |