首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >TList<T>抛出异常

TList<T>抛出异常
EN

Stack Overflow用户
提问于 2022-03-15 14:28:00
回答 1查看 101关注 0票数 0

我有以下代码:

代码语言:javascript
复制
program Tlist;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  madExcept,
  madLinkDisAsm,
  madListHardware,
  madListProcesses,
  madListModules,
  System.Generics.Collections,
  System.SysUtils;

type
  TMyItem = class(TInterfacedObject)
  private
    ItemPrice: Currency;
  public
    constructor Create(const aItemPrice: Currency); reintroduce;
  end;

  IMyList = interface
    ['{1D11BD29-5C1E-4171-B67E-FB9157DCB021}']
    function Reset(const aItems: Integer): Integer;
    function Add(const aPrice, aItemN: Integer): Integer;
  end;

  TMyList = class(TInterfacedObject, IMyList)
  private
    FList: array of TList<TMyItem>;
  public
    function Reset(const aItems: Integer): Integer;
    function Add(const aPrice, aItemN: Integer): Integer;
  end;

{ TMyList }

function TMyList.Add(const aPrice, aItemN: Integer): Integer;
begin
  FList[aItemN].Add(TMyItem.Create(aPrice));
  Result := FList[aItemN].Count;
end;

function TMyList.Reset(const aItems: Integer): Integer;
var
  I: Integer;
begin
  SetLength(FList, 0);
  SetLength(FList, aItems);
  for I := 0 to Length(FList) - 1 do
  begin
    FList[I] := TList<TMyItem>.Create;
  end;
  Result := Length(FList);
end;

{ TMyItem }

constructor TMyItem.Create(const aItemPrice: Currency);
begin
  ItemPrice := aItemPrice;
end;

var
  MyList: IMyList;

begin
  MyList := TMyList.Create;
  MyList.Reset(3);
  mylist.Add(1000, 1);
end.

执行时,它会抛出一个链接到TList<T>的异常。

由于TList实现了引用计数,而且所有的类都是从TInterfacedObject派生出来的,因此我的印象是内存将自动释放,但很明显,我错了。

我做错了什么?

编辑

根据这些建议,我提出了以下代码:

代码语言:javascript
复制
program Tlist2;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  madExcept,
  madLinkDisAsm,
  madListHardware,
  madListProcesses,
  madListModules,
  System.Generics.Collections,
  System.SysUtils;

type
  IMyItem = interface
    ['{2EB53CC3-E5FC-474B-A162-30BBD2D17C48}']
  end;

  TMyItem = class(TInterfacedObject, IMyItem )
  private
    ItemPrice: Currency;
  public
    constructor Create(const aItemPrice: Currency); reintroduce;
  end;

  IMyList = interface
    ['{1D11BD29-5C1E-4171-B67E-FB9157DCB021}']
    function Reset(const aItems: Integer): Integer;
    function Add(const aPrice, aItemN: Integer): Integer;
  end;

  TMyList = class(TInterfacedObject, IMyList)
  private
    FList: array of TList<TMyItem>;
  public
    function Reset(const aItems: Integer): Integer;
    function Add(const aPrice, aItemN: Integer): Integer;
    destructor Destroy; override;
  end;

{ TMyList }

function TMyList.Add(const aPrice, aItemN: Integer): Integer;
begin
  FList[aItemN].Add(TMyItem.Create(aPrice));
  Result := FList[aItemN].Count;
end;

destructor TMyList.Destroy;
var
  I: Integer;
  a: Integer;
begin
  for I := 0 to Length(FList) - 1 do
  begin
    if FList[I].Count > 0 then
    begin
      for a := 0 to FList[I].Count - 1 do
      begin
        FList[I][a].Destroy
      end;
    end;
    FList[I].Destroy;
  end;
  inherited;
end;

function TMyList.Reset(const aItems: Integer): Integer;
var
  I: Integer;
begin
  SetLength(FList, 0);
  SetLength(FList, aItems);
  for I := 0 to Length(FList) - 1 do
  begin
    FList[I] := TList<TMyItem>.Create;
  end;
  Result := Length(FList);
end;

{ TMyItem }

constructor TMyItem.Create(const aItemPrice: Currency);
begin
  ItemPrice := aItemPrice;
end;

var
  MyList: IMyList;


begin
  MyList := TMyList.Create;
  MyList.Reset(3);
  mylist.Add(1000, 1);
end.

这样做很好,没有更多的内存泄漏,但我的印象是,我错过了一些东西在这里。我认为,通过使用接口并从TInterfacedObject派生类,驱逐舰就没有必要了。

EN

回答 1

Stack Overflow用户

发布于 2022-03-16 13:30:50

根据David和Remi的输入,我修改了我的代码:

代码语言:javascript
复制
program Tlist3;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  madExcept,
  madLinkDisAsm,
  madListHardware,
  madListProcesses,
  madListModules,
  System.Generics.Collections,
  System.SysUtils;

type
  IMyItem = interface
    ['{2EB53CC3-E5FC-474B-A162-30BBD2D17C48}']
  end;

  TMyItem = class(TInterfacedObject)
  private
    ItemPrice: Currency;
  public
    constructor Create(const aItemPrice: Currency); reintroduce;
  end;

  IMyList = interface
    ['{1D11BD29-5C1E-4171-B67E-FB9157DCB021}']
    function Reset(const aItems: Integer): Integer;
    function Add(const aPrice, aItemN: Integer): Integer;
  end;

  TMyList = class(TInterfacedObject, IMyList)
  private
    FList: array of TObjectList<TMyItem>;
  public
    function Reset(const aItems: Integer): Integer;
    function Add(const aPrice, aItemN: Integer): Integer;
    destructor Destroy; override;
  end;

{ TMyList }

function TMyList.Add(const aPrice, aItemN: Integer): Integer;
begin
  FList[aItemN].Add(TMyItem.Create(aPrice));
  Result := FList[aItemN].Count;
end;

destructor TMyList.Destroy;
var
  I: Integer;
  a: Integer;
begin
  if Length(FList) > 0 then
  begin
    for I := 0 to Length(FList) - 1 do
    begin
      FList[I].Free;
    end;
  end;
  inherited;
end;

function TMyList.Reset(const aItems: Integer): Integer;
var
  I: Integer;
begin
  if Length(FList) > 0 then
  begin
    for I := 0 to Length(FList) - 1 do
    begin
      FList[I].Free;
    end;
  end;
  SetLength(FList, 0);
  SetLength(FList, aItems);
  for I := 0 to Length(FList) - 1 do
  begin
    FList[I] := TObjectList<TMyItem>.Create;
  end;
  Result := Length(FList);
end;

{ TMyItem }

constructor TMyItem.Create(const aItemPrice: Currency);
begin
  ItemPrice := aItemPrice;
end;

var
  MyList: IMyList;


begin
  MyList := TMyList.Create;
  MyList.Reset(3);
  mylist.Add(1000, 1);
  mylist.Add(2000, 2);
  MyList.Reset(2);
  mylist.Add(1000, 0);
  mylist.Add(2000, 1);
end.

没有内存泄漏。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71483943

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档