上课之间的循环引用

时间:2013-08-15 17:02:24

标签: delphi oop circular-reference

我需要开发下一个图表类: enter image description here
我编写了代码,但是,存在循环单元引用的问题。

XmlFileManager类包含:

unit XmlFileManager;
interface
uses
  xmldom, XMLIntf, msxmldom, XMLDoc, SysUtils, DateUtils, Classes, Dialogs,
  XmlEnpManager;
type
  TXmlFileManager = class
  private
    [...]
    xmEnp: TXmlEnpManager;
    xmEnpInicial: TXmlEnpManager;
    xmEnpFinal: TXmlEnpManager;
[...]
end.

抽象类,XmlNodeManager:

unit XmlNodeManager;
interface
uses
  xmldom, XMLIntf, msxmldom, XMLDoc, SysUtils, DateUtils, Classes, Dialogs,
  XmlFileManager;
type
  TXmlNodeManager = class
   protected
        { sgy alias para strategy }
        sgyIterator: Integer;
        sgyContext: TXmlFileManager;
        sgyAttributes: TStringList;
        sgyNode: IXMLNode;
[...]
end.

和XmlEnpManager具体类:

unit XmlEnpManager;
interface
uses
  xmldom, XMLIntf, msxmldom, XMLDoc, SysUtils, DateUtils, Classes, Dialogs,
  XmlNodeManager;
type
  TXmlEnpManager = class (TXmlNodeManager)
    public
        constructor Create(aContext: TXmlFileManager); overload; override;
        constructor CreateInicial(aContext: TXmlFileManager); reintroduce; overload;
        constructor CreateFinal(aContext: TXmlFileManager); reintroduce; overload;
[...]
end.

构建失败并显示错误:

  

[dcc32致命错误] XmlNodeManager.pas(7):F2047循环单位   引用'XmlFileManager'

任何想法如何解决这个问题?。

5 个答案:

答案 0 :(得分:5)

TXmlFileManagerTXmlNodeManager放在同一个unit和同一type部分中,然后确保type部分以此课程开头: TXmlNodeManager = class;

请参阅官方文档:Forward Declarations and Mutually Dependent Classes

unit XmlFileManagerAndXmlNodeManager;
interface
uses
  xmldom, XMLIntf, msxmldom, XMLDoc, SysUtils, DateUtils, Classes, Dialogs,
[...]

type
  TXmlNodeManager = class;

  TXmlFileManager = class
  private
    [...]
    xmEnp: TXmlEnpManager;
    xmEnpInicial: TXmlEnpManager;
    xmEnpFinal: TXmlEnpManager;
[...]

  TXmlNodeManager = class
   protected
        sgyIterator: Integer;
        sgyContext: TXmlFileManager;
        sgyAttributes: TStringList;
        sgyNode: IXMLNode;
[...]
end.

答案 1 :(得分:1)

如果可能,最简单的方法是让所有班级都在同一个单位。

答案 2 :(得分:1)

尽管将所有类放在同一个单元中是一个完美的解决方案,但您可以考虑通过连接至少一个类来断开相互引用,在单独的单元中定义该接口并让其他单元引用该单元接口部分的接口。然后,您可以将第一个单元引用从接口移动到实现。然后将在实现部分中创建实例,其中允许相互引用,但因此在接口部分中断开了相互引用,这不是正如你已经注意到的那样。如果需要,这允许您将两个类保持在单独的单元中。 希望这是有道理的。

答案 3 :(得分:0)

如果单元之间的引用位于实现部分而不是接口部分,那么这将起作用。

您可以在另一个单元中创建一个没有输出引用的基类,并从接口引用它,并通过向实现部分添加特定单元引用按需转换为实际类。

答案 4 :(得分:0)

在XMLNodeManager中,Make:

sgyContext: TObject;

然后您不需要在界面中使用单元XmlFileManager。在Implementation部分的Uses子句中使用它。在实现代码中使用sgyContext时,将其强制转换为TXmlFileManager(sgyContext)。