【发布时间】:2013-08-18 06:56:58
【问题描述】:
我有两节课。一个抽象 (XmlNodeManager) 和您的具体子 XmlEnpManager。 抽象类定义为:
type
TXmlNodeManager = class
public
constructor Create(aRoot: IXMLNode); virtual; abstract;
function Size(): Integer;
protected
{ sgy alias para strategy }
sgyIterator: Integer;
sgyAttributes: TStringList;
sgyRoot: IXMLNode;
end;
还有,子类:
type
TXmlEnpManager = class (TXmlNodeManager)
public
constructor Create(aRoot: IXMLNode); override;
end;
构造函数在子类中实现,代码如下:
constructor TXmlEnpManager.Create(aRoot: IXMLNode);
begin
sgyIterator := 0;
sgyRoot := aRoot;
Self.GenerateAttribs;
end;
而 size() 方法是在父亲中实现的:
function TXmlNodeManager.Size(): Integer;
begin
Size := sgyRoot.ChildNodes.Count;
end;
当我创建 XmlEnpManager 的实例,并将定义的 IXMLNode 作为参数传递,并发送 Size() 消息时。程序因 sgyRoot.ChildNodes.Count 上的访问冲突而失败(在执行时)。
我做下一个检查:
function TXmlNodeManager.Size(): Integer;
begin
if (Assigned(sgyRoot)) then
ShowMessage('Root assigned.')
else
ShowMessage('Root not assigned ???');
end;
显示第二个警报。我在 Delphi 中是最新的,并且怀疑接口引用是按值引用的,与对象不同。是正确的 ?。 如何解决这个问题?有什么想法吗?。
编辑:我做向下转换。我有一个 XmlNodeManager 类型的变量,它使用 XmlNodeManager 的子类进行初始化。这是对的 ?。示例:
// aNode can be a instance of TXmlEnpManager or another subclass of TXmlNodeManager.
procedure TXmlFileManager.SetCurrentNode(aNode: TXmlNodeManager);
begin
// xmCurrentNode is of TXmlNodeManager type
xmCurrentNode := aNode;
end;
【问题讨论】:
-
我仍然建议您在构造函数中进行相同的检查,
if Assigned(aRoot) ..,或者“GenerateAttribs”可能正在覆盖接口。 -
@SertacAkyuz 是的,已分配。抱歉,我不解释 GenerateAttribs 是做什么的,这个方法创建一个 TListString,不再赘述。
-
@ramiromd:显示调用
TXmlEnpManager.Create()的代码。鉴于您显示的代码,调用者可能会将 nilIXMLNode传递给Create(),无论如何您都应该在Size()中检查:if Assigned(sgyRoot) then Result := sgyRoot.ChildNodes.Count else Result := 0; -
Debug it. 关注数据。确认您调用了您认为正在调用的构造函数。然后确认构造函数接收到你认为的接口。最后,确认您调用
Size的对象与您之前调用构造函数得到的对象相同。调试器可以帮助您完成每个步骤。 -
如果你不能自己调试,而且如果你只是尝试调试看起来很简单,那么你需要提供一个 SSCCE。
标签: delphi interface reference