这段代码中的构造函数不好。有人可以帮我管理这段代码吗?

时间:2015-08-16 09:30:19

标签: delphi

我有一个项目和两个单元和主程序 第一个单元在这里是这个类的构造函数的主要问题:

unit dl_tPA_MailJournal;

interface
uses
  Windows,
  Generics.Collections,
  SysUtils,
  uInterfaces;
  type
    TtPA_MailJournal = class(TInterfacedObject ,ITable)
      public
      function GetanQId: integer;
      procedure SetanQId(const Value: integer);
      function GetadDate: TDateTime;
      procedure SetadDate(const Value: TDateTime);

      function toList: TList<string>;

      constructor Create(aId : Integer; aDate : TDateTime);


      private
      property anQId : integer read GetanQId write SetanQId;
      property adDate : TDateTime read GetadDate write SetadDate;


    end;

implementation

{ TtPA_MailJournal }

constructor TtPA_MailJournal.Create(aId : Integer; aDate : TDateTime);
begin
  SetanQId(aId);
  SetadDate(aDate);
end;

function TtPA_MailJournal.GetadDate: TDateTime;
begin
  Result := adDate;
end;

function TtPA_MailJournal.GetanQId: integer;
begin
  Result := anQId ;
end;

procedure TtPA_MailJournal.SetadDate(const Value: TDateTime);
begin
  adDate := Value;
end;

procedure TtPA_MailJournal.SetanQId(const Value: integer);
begin
  anQId := Value;
end;
function TtPA_MailJournal.toList: TList<string>;
var aListTable: TList<TtPA_MailJournal>;
var aTable: TtPA_MailJournal;
var aListString: TList<String>;
begin
  aTable.Create(1,now);
  aListTable.Add(aTable);
  aTable.Create(2,now);
  aListTable.Add(aTable);
  aListString.Add(aListTable.ToString);

  Result := aListString;
end;
end.

第二个单位是一个在这里看不多的界面

unit uInterfaces; 

interface
uses Generics.Collections;
type

  ITable = Interface
  ['{6CED8DCE-9CC7-491F-8D93-996BE8E4D388}']
    function toList: TList<String>;
    End;

implementation

end.

主要类,在这里我想得到stringlist泛型并放入网格中:

unit MainUnit;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  dl_tPA_MailJournal,uInterfaces, Vcl.StdCtrls,
  Generics.Collections, Vcl.Grids;

type
  TForm1 = class(TForm)
    Button1: TButton;
    StringGrid1: TStringGrid;
    procedure Button1Click(Sender: TObject);

  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;


implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var MyTable: TtPA_MailJournal;
    MyList: TList<String>;
    AStringList: TStrings;
    StrDate : string;
    Fmt: TFormatSettings;
begin

    //fmt.ShortDateFormat:='dd/mm/yyyy';
   // fmt.DateSeparator  :='/';
   // StrDate:='23/02/2011' ;


    MyTable := TtPA_MailJournal.Create(1,now);       //strtodate(strdate,fmt)

    MyList := MyTable.toList;

     AStringList := TStringList.Create;
     AStringList.Add(MyList.ToString);
     StringGrid1.Cols[1].Add(MyList.ToString);
     FreeAndNil(MyTable);




end;

end.

当我点击按钮时,程序会崩溃。当我评论这两个 构造函数SetanQId(aId)的行;和SetadDate(aDate);没关系 我做错了可以有人告诉我如何管理这个代码以网格显示。

1 个答案:

答案 0 :(得分:2)

声明属性不会为该属性分配任何存储空间。它只是指向值存储位置的指针。虽然您可以声明getter和setter函数来访问属性值,但最终属性值必须由某个字段备份。

TtPA_MailJournal = class(TInterfacedObject ,ITable)
public
  FanId: integer;
  FadDate: TDateTime; 
  function GetanQId: integer;
  procedure SetanQId(const Value: integer);
  function GetadDate: TDateTime;
  procedure SetadDate(const Value: TDateTime);

  function toList: TList<string>;

  constructor Create(aId : Integer; aDate : TDateTime);
private
  property anQId : integer read GetanQId write SetanQId;
  property adDate : TDateTime read GetadDate write SetadDate;
end;

function TtPA_MailJournal.GetadDate: TDateTime;
begin
  Result := FadDate;
end;

function TtPA_MailJournal.GetanQId: integer;
begin
  Result := FanQId ;
end;

procedure TtPA_MailJournal.SetadDate(const Value: TDateTime);
begin
  FadDate := Value;
end;

procedure TtPA_MailJournal.SetanQId(const Value: integer);
begin
  FanQId := Value;
end;

如果您对getter和setter方法没有任何特殊需求,可以声明您的属性直接访问其存储字段:

  property anQId : integer read FanQId write FanQId;
  property adDate : TDateTime read FadDate write FadDate;

此外,只有在getter和/或setter方法中实现了一些额外的逻辑时,才能使用私有属性。在这种特殊情况下,它们没有多大意义,因此您可以完全删除属性声明,并直接使用字段。

constructor TtPA_MailJournal.Create(aId : Integer; aDate : TDateTime);
begin
  inherited Create;
  FanQId := aId;
  FadDate := aDate;
end;

首先,您需要初始化Result和aListTable变量。然后你以错误的方式使用构造函数而不是aTable.Create(1, now)你应该使用aTable := TtPA_MailJournal.Create(1,now)

您在这里遇到的另一个问题是您正在混合对象和接口引用,从而泄漏对象。因此,您应该使用ITable来存储对TtPA_MailJournal对象实例的引用。

function TtPA_MailJournal.toList: TList<string>;
var 
  aListTable: TList<ITable>;
  aTable: ITable;
begin
  Result := TList<String>.Create;
  try
    aListTable := TList<ITable>.Create;
    aTable := TtPA_MailJournal.Create(1,now);
    aListTable.Add(aTable);

    aTable := TtPA_MailJournal.Create(2,now);
    aListTable.Add(aTable);
    Result.Add(aListTable.ToString);
  finally
    aListTable.Free;
  end;
end;

完成后,您还应释放MyList对象,否则会泄漏内存。

相关问题