【问题标题】:Abstract error when changing TStringList to TStrings将 TStringList 更改为 TStrings 时出现抽象错误
【发布时间】:2014-11-28 22:28:25
【问题描述】:

好吧,这变得很愚蠢......

这是第二次(第一次是 30 分钟前,在获取目录树的函数上)我看到错误“抽象错误”,真的不知道为什么会发生。

我有这个功能,列出所有的硬盘:

function TForm2.GetDriveList:TStringList;
 var
    s:string;
    i:integer;
    DriveStr:array[1..255] of char;
    t:integer;
  begin
    GetLogicalDriveStrings(255,@DriveStr);
    result:=TStringList.create;
    i:=1;
    repeat
      s:='';
      while (i<=255) and (DriveStr[i]<>#00) do
      begin
        s:=s+char(drivestr[i]);
        inc(i);
      end;
      inc(i); {step over #00}
      t:=getdrivetype(Pchar(s));
      if (length(s)>0) and (t=DRIVE_FIXED)

        then result.add(s);
    until length(s)=0;

 end;

现在,我将 TStringList 更改为 TStrings,但在尝试调用它时出现此抽象错误;

我也试过改成procedure,如

procedure TFrom2.GetDriveList(List: TStrings);

从代码中删除结果,并在末尾添加 List.Add(s);

这个(函数到过程)在我的第一个案例中以某种方式解决了这个问题,但在这个案例中没有。

我的问题是: 上面的代码有什么问题,为什么不接受 TStrings...?

并且:这些抽象错误到底是什么,如何识别它们,因为它们出现在函数/过程的最后(通过调试检查),在它基本上已经完成之后?

【问题讨论】:

  • 你不应该实例化 TStrings。请查阅精美的文档。
  • 这是什么意思?实例化...?如果我尝试将 StringList 结果分配给 TStrings 类型的变量,我会得到同样的错误...为什么它可以与 Listbox1.Items.Assign 一起使用,其中 Items 是 TStrings...?
  • 发生这种情况是因为 TListBox.Items 在内部不是 TStrings,但这是完全不同的故事。
  • 好的,现在知道了。从@David 的回答我明白你们俩的意思......
  • @TLama 谢谢!看起来不错。我必须尝试一下,虽然现在上面的代码也可以根据需要工作......但是有另一个/更好的选择很好:)

标签: delphi


【解决方案1】:

TStrings 是一个抽象基类。它不能被实例化。它作为具体派生类的公共基类而存在。就像TStringList 一样,就像TMemoTListBox 等暴露的TStrings 派生类。文档说:

TStrings 是表示字符串列表的对象的基类。

从 TStrings 派生一个类来存储和操作字符串列表。 TStrings 包含抽象方法,或者用 C++ 术语来说,纯虚方法,不应直接实例化。

规则明确。不要实例化TStrings

抽象错误是调用抽象方法时出现的运行时错误。抽象方法是没有实现的虚拟方法。不能调用抽象方法。这就是为什么不应该实例化抽象类的原因。

如果您不熟悉什么是抽象方法,那么您需要返回文档并复习知识。从这里开始:http://docwiki.embarcadero.com/RADStudio/en/Methods#Virtual_and_Dynamic_Methods

【讨论】:

  • 好的。所以说,永远不要使用 TStrings 类型。承认...不知道...伙计,德尔福很有趣.. :)
  • 没有。您可以使用 TStrings。例如作为参数类型,以便与任何后代兼容。只是不要实例化它。就像 TStream 一样。
  • 是的,我知道我仍然可以将它作为参数传递,但我不能以其他方式声明它......?
  • 您可以将变量声明为 TStrings 类型并分配派生类的实例。您只是不能实例化 TStrings。你唯一不能做的就是 TStrings.Create。
  • @LDFreak 也许你根本不明白instantiate这个词的意思。简单地说,就是在您创建 instance 时,因此术语相似。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多