Circular reference issue with Classes which use each other

你离开我真会死。 提交于 2019-12-24 11:30:14

问题


I have the following two classes:

TcmTPDataPanel = class(TcmTPBasePanel)
    Database: TnxDatabase;
    Session: TnxSession;
  private
    FDataConnector: TcmTPDataConnector;
    MyNxDataBase: TnxDatabase;
    MyNxSession: TnxSession;
    MyRefNxDataBase: TnxDatabase;
  protected
    procedure Disconnect; virtual; abstract;
    procedure Refresh; virtual;
    procedure Requery; virtual; abstract;
  public
    procedure Connect;
  published
    property DataConnector: TcmTPDataConnector read FDataConnector write
        FDataConnector;
  end;


TcmTPDataConnector = class(TComponent)
  private
    FDatabase: TnxDatabase;
    FObservers: TList;
    FTableForCategories: TnxTable;
    FTableForItemCategoryLinks: TnxTable;
    FTableForItems: TnxTable;
    procedure SetTableForItemCategoryLinks(const Value: TnxTable);
  protected
    procedure IterateObservers;
  public
    constructor Create;
    destructor Destroy; override;
    procedure Register(Instance: TcmTPDataPanel);
    procedure Unregister(Instance: TcmTPDataPanel);
  published
    property Database: TnxDatabase read FDatabase write FDatabase;
    property TableForCategories: TnxTable read FTableForCategories write
        FTableForCategories;
    property TableForItemCategoryLinks: TnxTable read
        FTableForItemCategoryLinks write SetTableForItemCategoryLinks;
    property TableForItems: TnxTable read FTableForItems write FTableForItems;
  end;

TcmDataPanel is a (3rd generation) TFrame descendent. It's not used directly, but rather multiple other compound components descend from it.

TcmDataConnector is a component which holds the database connection information for these other components.

I'm using ModelMaker, and am trying to implement an Observer pattern so that multiple "Data Panels" can be automatically updated whenever the "Data Connector" changes state.

Here's my problem: I can't seem to get around the "circular refernece" problem, as each class uses the other in the Interface section. Putting the associated "uses" reference in the Interface section doesn't clear up the "Undeclared identifier" issue, and putting them both in the same unit doesn't either. Right now they are in the same unit (I've tried them in separate units, and together), and I get the "Undeclared identifier: TcmTPDataConnector" error.

How can I get around this?

================
UPDATE:

It's Friday night at 9:30pm where I am, and I was totally stuck. Just MINUTES after my post, you people SAVED THE DAY!! (night!) THANK YOU!!

Man, I love StackOverflow.... SO my friend in this learning-like-crazy season. : ) Thank you, thank you, thank you...


回答1:


On the same unit, try the following:

TcmTPDataConnector = class(TComponent);


TcmTPDataPanel = class(TcmTPBasePanel)
   ... 
end;

TcmTPDataConnector = class(TComponent)
  ...
end;



回答2:


Yet another option is to use interfaces, but I think in this case it would be overengineered.




回答3:


Two options:

1) Put them in the same unit, the same Type block within it. Forward declare TcmTPDataConnector, declare the other type and then declare it. (See jcinacio's post)

2) Make an ancestor of TcmTPDataConnector that contains what needs to be available externally and make your references be to that. This is more of a headache but allows you to do it across multiple units.



来源:https://stackoverflow.com/questions/692173/circular-reference-issue-with-classes-which-use-each-other

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!