Circular link between class

I need to develop the following class of diagrams: enter image description here
I wrote the code, but, you have problems with the reference to round units.

The XmlFileManager class contains:

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

Abstract class, 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. 

And a specific XmlEnpManager class:

 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. 

Build failed with error:

[dcc32 Fatal Error] XmlNodeManager.pas (7): F2047 Circular block link to "XmlFileManager"

Any ideas how to solve this problem?

+4
source share
5 answers

Put TXmlFileManager and TXmlNodeManager in the same unit and the same type section, then make sure the type section starts from this class forward: TXmlNodeManager = class;

See white paper: Variable Declarations and Interdependent 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. 
+5
source

If possible, the easiest way is to have all classes in the same unit.

+1
source

Despite the fact that placing all classes in the same block is an ideal solution, you can consider the possibility of breaking mutual links by interacting with at least one of the classes, defining this interface in a separate block and allowing another device to refer to the device using the interface in interface section. Then you can transfer the first link to the unit from the interface to the implementation. Then an instance will be created in the implementation section, where mutual reference is allowed, but thereby violating the mutual reference in the interface section, which is not allowed, as you already noticed. This allows you to store both classes in a separate block, if necessary. Hope this makes sense.

+1
source

If the link between the blocks is in the implementation section instead of the interface section, this will work.

You can create a base class in another module without reference to it and refer to it from the interface and insert it into the actual class on demand by adding a link to a specific unit in the implementation section.

0
source

In the XMLNodeManager Make:

sgyContext: TObject;

Then you do not need to use the XmlFileManager module in the interface. Use it in the Usage section of the Usage section. When using sgyContext in the implementation code, pass it to TXmlFileManager (sgyContext).

0
source

Source: https://habr.com/ru/post/1497284/


All Articles