4

我需要开发下一个图表类: 在此处输入图像描述
我写了代码,但是,有循环单元引用的问题。

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'

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

4

5 回答 5

5

TXmlFileManagerandTXmlNodeManager放在相同unit和相同的type部分中,然后确保该type部分以此类向前开始:TXmlNodeManager = class;

请参阅官方文档:前向声明和相互依赖的类

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.
于 2013-08-15T20:05:39.910 回答
1

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

于 2013-08-17T18:20:04.493 回答
1

如果可能,最简单的方法是将所有课程放在同一个单元中。

于 2013-08-15T17:09:44.080 回答
0

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

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

于 2013-08-15T17:05:31.440 回答
0

在 XMLNodeManager 中,制作:

sgyContext: TObject;

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

于 2013-08-15T17:36:23.940 回答