Delphi 在实例变量上访问冲突
我有两节课。一个抽象(XmlNodeManager)和您的具体子XmlEnpManager。 抽象类定义为:Delphi 在实例变量上访问冲突,delphi,interface,reference,Delphi,Interface,Reference,我有两节课。一个抽象(XmlNodeManager)和您的具体子XmlEnpManager。 抽象类定义为: type TXmlNodeManager = class public constructor Create(aRoot: IXMLNode); virtual; abstract; function Size(): Integer; protected { sgy alias para strategy } sgyIte
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作为param传递,然后发送Size()消息时。程序失败(在执行时),在sgyRoot.ChildNodes.Count上出现访问冲突
我做下一个检查:
function TXmlNodeManager.Size(): Integer;
begin
if (Assigned(sgyRoot)) then
ShowMessage('Root assigned.')
else
ShowMessage('Root not assigned ???');
end;
显示第二个警报。Im是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;
如果我没有弄错,您应该从构造函数调用继承的构造函数:
constructor TXmlEnpManager.Create(aRoot: IXMLNode);
begin
INHERITED Create;
sgyIterator := 0;
sgyRoot := aRoot;
Self.GenerateAttribs;
end;
我仍然建议您在构造函数中执行相同的检查,
如果已分配(aRoot)
,或者“GenerateAttribs”正在覆盖接口。@SertacAkyuz yes,已分配。对不起,我没有解释GenerateAttribs的作用,这个方法只创建了一个TListString,没有更多。@ramiromd:显示调用TXmlEnpManager.Create()
的代码。给定您显示的代码,调用方可能会将nilIXMLNode
传递给Create()
,您应该在Size()
中检查该值:如果已分配(sgyRoot),则结果:=sgyRoot.ChildNodes.Count否则结果:=0代码>跟随数据。确认您调用了您认为正在调用的构造函数。然后确认构造函数收到了您认为它收到的接口。最后,确认您调用的Size
对象与之前调用构造函数得到的对象相同。调试器可以帮助您完成这些步骤中的每一步。如果您自己无法调试此步骤,并且如果您只是尝试,调试看起来非常简单,那么您将需要提供一个SSCCE。继承的构造函数是抽象的,因此编译器将忽略您添加的代码。编译器将发出与问题中的源代码相同的目标代码。更糟糕的是,如果它将编译,则会导致抽象错误(继承的构造函数签名不同)。您错了。继承的构造函数是抽象的,因此忽略调用它显然不是问题的原因。然而,继承调用的缺乏确实表明了类的糟糕设计。构造器可能没有理由是虚拟的,更不用说抽象的了。类应该始终负责初始化自己的字段,因此基类应该是分配给sgyRoot
、sgyIterator
和sgyAttributes
的类。如果有什么东西应该是抽象的,那就是GenerateAttribs
,它应该填充而不是分配sgyAttributes
。尽管如此,这并不能回答问题。你确定吗?我知道它不会调用直接父级的构造函数(它没有无参数构造函数),但我希望它调用TObject.Create,从而将对象的所有内存清除为零。TObject.Create不做任何事情。是NewInstance,它将对象初始化为零。既然你知道这个答案是错误的,我不明白你为什么不删除它。留下不准确的答案对社区没有帮助。