组件创建问题:字段最终为零

发布于 2024-07-16 01:21:17 字数 3219 浏览 4 评论 0原文

这是我在这里从事的项目的延续: 相互使用的类的循环引用问题

那里收到的建议修复了圆形参考问题(再次感谢您的帮助)。 现在我正在与其他东西摔跤:TcmDataPanel.FObservingDataPanels 总是以 = nil 结束,显然是因为它永远不会被创建。 (最初我遇到了访问冲突,但经过进一步测试发现 FObserver 始终为零)。

下面是相关代码(它是一个 TFrame 单元,TcmTPDataPanel 是 TFrame 的后代):

unit cmTPDataPanelFrame;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, cmTPBasePanelFrame, cmTPPanels, nxdb, nxllComponent;

type
  TcmTPDataConnector = class;

  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;

  TcmTPCustomDataConnector = class(TComponent)
  private
    FDatabase: TnxDatabase;
    FObservingDataPanels: TList;
    FTableForCategories: TnxTable;
    FTableForItemCategoryLinks: TnxTable;
    FTableForItems: TnxTable;
    procedure SetTableForItemCategoryLinks(const Value: TnxTable);
  protected
    procedure IterateObservers;
  public
    constructor Create(AOwner: TComponent);
    destructor Destroy; override;
    procedure Register(Instance: TcmTPDataPanel);
    procedure ReportObservers;
    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;

  TcmTPDataConnector = class(TcmTPCustomDataConnector)
  end;


var
  cmTPDataPanel: TcmTPDataPanel;

implementation

=== 和 ===

{
*************************** TcmTPCustomDataConnector ***************************
}
constructor TcmTPCustomDataConnector.Create(AOwner: TComponent);
begin
  ShowMessage('TcmTPCustomDataConnector.Create entered.');
//  inherited Create(AOwner); // TODO : check duplicate
  FObservingDataPanels := TList.Create();
end;

destructor TcmTPCustomDataConnector.Destroy;
begin
  FreeAndNil(FObservingDataPanels);
//inherited Destroy; // TODO : check duplicate
end;

我希望在 cmTPDataConnector.Create 上运行的 ShowMessage 行从未出现,这让我认为它不是继承TcmTPCUstomDataConnector 的 Create 方法。 难道不应该吗?

“感觉”好像我错过了一些明显的东西,但我没有看到它。 :-\

两个问题:

1) 为什么 FObservingDataPanels 没有被创建?
2) “//inheritedCreate(AOwner);//TODO:checkduplicate”和“//inheritedDestroy;//TODO:checkduplicate”行是由 ModelMaker 在某个时刻放入的。 他们应该被取消评论吗?

PS 显然,我仍在学习组件创建和继承。 欢迎任何其他意见和建议。

PPS 今天我提出了很多问题。 如果我需要降低一个档次,请随时告诉我......(只是在这里有一个额外的问题很多的日子)。

预先感谢您的任何和所有帮助! :)

This is a continuation of the project I was working on here:
Circular reference issue with Classes which use each other

The advice received there fixed the ciruclar reference problem (again, thanks for the help). Now I'm wrestling w/something else: TcmDataPanel.FObservingDataPanels always ends up = nil, apparently because it never gets created. (Initially I was getting an Access Violation, but on further testing it turned out that FObserver was always nil).

Here is the relevant code (it is a TFrame unit, with TcmTPDataPanel being the TFrame descednent):

unit cmTPDataPanelFrame;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, cmTPBasePanelFrame, cmTPPanels, nxdb, nxllComponent;

type
  TcmTPDataConnector = class;

  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;

  TcmTPCustomDataConnector = class(TComponent)
  private
    FDatabase: TnxDatabase;
    FObservingDataPanels: TList;
    FTableForCategories: TnxTable;
    FTableForItemCategoryLinks: TnxTable;
    FTableForItems: TnxTable;
    procedure SetTableForItemCategoryLinks(const Value: TnxTable);
  protected
    procedure IterateObservers;
  public
    constructor Create(AOwner: TComponent);
    destructor Destroy; override;
    procedure Register(Instance: TcmTPDataPanel);
    procedure ReportObservers;
    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;

  TcmTPDataConnector = class(TcmTPCustomDataConnector)
  end;


var
  cmTPDataPanel: TcmTPDataPanel;

implementation

=== and ===

{
*************************** TcmTPCustomDataConnector ***************************
}
constructor TcmTPCustomDataConnector.Create(AOwner: TComponent);
begin
  ShowMessage('TcmTPCustomDataConnector.Create entered.');
//  inherited Create(AOwner); // TODO : check duplicate
  FObservingDataPanels := TList.Create();
end;

destructor TcmTPCustomDataConnector.Destroy;
begin
  FreeAndNil(FObservingDataPanels);
//inherited Destroy; // TODO : check duplicate
end;

The ShowMessage line that I expect to run on cmTPDataConnector.Create never shows up, which makes me think it's not inheriting the Create method from TcmTPCUstomDataConnector. Shouldn't it be?

It "feels" like there is something obvious I'm missing, but I'm not seeing it. :-\

Two questions:

1) Why is FObservingDataPanels not getting created?
2) The "// inherited Create(AOwner); // TODO : check duplicate" and "//inherited Destroy; // TODO : check duplicate" lines were put in by ModelMaker at some point. Should they be uncommented?

P.S. Obviously, I'm still learning about component creation and inheritance. Any other input and advice is welcome.

P.P.S. Lots of questions from me today. Feel free to let me know if I need to drop it down a notch.... (just having a bonus lots-of-questions day here).

Thanks in advance for any and all help! : )

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

流星番茄 2024-07-23 01:21:17

您需要重写构造函数,然后调用继承作为该构造函数中的/first/ 事物。

  public
    constructor Create(AOwner: TComponent); override;



constructor TcmTPCustomDataConnector.Create(AOwner: TComponent);
begin
  inherited Create(AOwner); // TODO : check duplicate
  ShowMessage('TcmTPCustomDataConnector.Create entered.');
  FObservingDataPanels := TList.Create();
end;

You need to override your constructor, and then call inherited as the /first/ thing in that constructor.

  public
    constructor Create(AOwner: TComponent); override;



constructor TcmTPCustomDataConnector.Create(AOwner: TComponent);
begin
  inherited Create(AOwner); // TODO : check duplicate
  ShowMessage('TcmTPCustomDataConnector.Create entered.');
  FObservingDataPanels := TList.Create();
end;
手心的海 2024-07-23 01:21:17

我对 Delphi 很生疏,但我认为您可能需要对构造函数声明进行“覆盖”。

I'm rusty on Delphi, but I think you may need an "override" on your constructor declaration.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文