1
votes

Ok this is becoming quite silly...

It's the second time (the first time was 30min before, on a function to get directory tree) I ever see the error "Abstract error", and really can't tell why would it happen.

I had this function, to list all of the hard drives:

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;

Now, I changed the TStringList to TStrings, and I get this Abstract error when trying to call it;

I also tried to change it to procedure, as

procedure TFrom2.GetDriveList(List: TStrings);

removing the result from the code, and having List.Add(s) at the end;

This (function to procedure) somehow solved the issue in my first case, but doesn't on this one.

My questions are: What is wrong in the code above, and why is TStrings not accepted...?

and: what the heck are these abstract errors, how to identify them, since they appear (by debug inspection) on the very end of the function/procedure, after it is basically already done?

1
You are not supposed to instantiate TStrings. Please consult the fine documentation. - Free Consulting
What does this mean? Instantiate...? I get the same error if I try to assign the StringList result to a variable of type TStrings... Why does it work with Listbox1.Items.Assign, where Items are TStrings...? - LDFreak
That happens because TListBox.Items isn't TStrings internally, but this is completely different story. - Free Consulting
Ok, got it now. From @David's answer I see what you both mean... - LDFreak
@TLama Thanks! That looks nice. I'll have to try it, although right now the code above works as needed too so... But good to have another/better option :) - LDFreak

1 Answers

11
votes

TStrings is an abstract base class. It must not be instantiated. It exists to be a common base class for concrete derived classes. Like TStringList for one, like the TStrings derived classes exposed by TMemo, TListBox and so on. The documentation says:

TStrings is the base class for objects that represent a list of strings.

Derive a class from TStrings to store and manipulate a list of strings. TStrings contains abstract or, in C++ terminology, pure virtual methods and should not be directly instantiated.

The rule is stated clearly. Do not instantiate TStrings.

An abstract error is the runtime error that arises when you call an abstract method. An abstract method is a virtual method that has no implementation. Abstract methods cannot be called. This is why abstract classes should not be instantiated.

If you are not familiar with what an abstract method is then you need to go back to the documentation and brush up your knowledge. Start here: http://docwiki.embarcadero.com/RADStudio/en/Methods#Virtual_and_Dynamic_Methods