我在程序里这样用TStrings
var
  ss: TStrings;  ss := TStrings.Create;
  ss.LoadFromFile('File1.txt');
出错,Abstract Error.意思好像这是一个纯虚函数,
我这样用是可以的.
Memo1.Lines.LoadFromFile('File1.txt');
其中Lines是一个TStrings类型的成员
莫非在TMemo中重载了Lines.LoadFromFile()?Object Pascal可以有这样的重载的?
  

解决方案 »

  1.   

    A string list is typically part of a component. There are times, however, when it is convenient to create independent string lists, for example to store strings for a lookup table. The way you create and manage a string list depends on whether the list is short-term (constructed, used, and destroyed in a single routine) or long-term (available until the application shuts down). Whichever type of string list you create, remember that you are responsible for freeing the list when you finish with it.Short-term string listsIf you use a string list only for the duration of a single routine, you can create it, use it, and destroy it all in one place. This is the safest way to work with string lists. Because the string-list object allocates memory for itself and its strings, you should use a try...finally block to ensure that the memory is freed even if an exception occurs.1 Construct the string-list object.
    2 In the try part of a try...finally block, use the string list.
    3 In the finally part, free the string-list object.The following event handler responds to a button click by constructing a string list, using it, and then destroying it.procedure TForm1.Button1Click(Sender: TObject);var
      TempList: TStrings; { declare the list }
    begin
      TempList := TStringList.Create; { construct the list object }
      try
        { use the string list }
      finally
        TempList.Free; { destroy the list object }
      end;
    end;Long-term string listsIf a string list must be available at any time while your application runs, construct the list at start-up and destroy it before the application terminates.1 In the unit file for your application抯 main form, add a field of type TStrings to the form抯 declaration.
    2 Write an event handler for the main form抯 constructor, which executes before the form appears. It should create a string list and assign it to the field you declared in the first step.
    3 Write an event handler that frees the string list for the form抯 OnClose event.This example uses a long-term string list to record the user抯 mouse clicks on the main form, then saves the list to a file before the application terminates.unit Unit1;interface
    uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
    {For CLX: uses SysUtils, Classes, QGraphics, QControls, QForms, Qialogs;}
    type
      TForm1 = class(TForm)
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
        procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
      private
        { Private declarations }  public
        { Public declarations }
        ClickList: TStrings; { declare the field }
      end;
    var
      Form1: TForm1;
    implementation
    {$R *.DFM}
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      ClickList := TStringList.Create; { construct the list }
    end;
    procedure TForm1.FormDestroy(Sender: TObject);
    begin
      ClickList.SaveToFile(ChangeFileExt(Application.ExeName, '.LOG')); { save the list }  ClickList.Free; { destroy the list object }
    end;
    procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      ClickList.Add(Format('Click at (%d, %d)', [X, Y])); { add a string to the list }
    end;
    end.
      

  2.   

    A string list is typically part of a component. There are times, however, when it is convenient to create independent string lists, for example to store strings for a lookup table. The way you create and manage a string list depends on whether the list is short-term (constructed, used, and destroyed in a single routine) or long-term (available until the application shuts down). Whichever type of string list you create, remember that you are responsible for freeing the list when you finish with it.Short-term string listsIf you use a string list only for the duration of a single routine, you can create it, use it, and destroy it all in one place. This is the safest way to work with string lists. Because the string-list object allocates memory for itself and its strings, you should use a try...finally block to ensure that the memory is freed even if an exception occurs.1 Construct the string-list object.
    2 In the try part of a try...finally block, use the string list.
    3 In the finally part, free the string-list object.The following event handler responds to a button click by constructing a string list, using it, and then destroying it.procedure TForm1.Button1Click(Sender: TObject);var
      TempList: TStrings; { declare the list }
    begin
      TempList := TStringList.Create; { construct the list object }
      try
        { use the string list }
      finally
        TempList.Free; { destroy the list object }
      end;
    end;Long-term string listsIf a string list must be available at any time while your application runs, construct the list at start-up and destroy it before the application terminates.1 In the unit file for your application抯 main form, add a field of type TStrings to the form抯 declaration.
    2 Write an event handler for the main form抯 constructor, which executes before the form appears. It should create a string list and assign it to the field you declared in the first step.
    3 Write an event handler that frees the string list for the form抯 OnClose event.This example uses a long-term string list to record the user抯 mouse clicks on the main form, then saves the list to a file before the application terminates.unit Unit1;interface
    uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
    {For CLX: uses SysUtils, Classes, QGraphics, QControls, QForms, Qialogs;}
    type
      TForm1 = class(TForm)
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
        procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
      private
        { Private declarations }  public
        { Public declarations }
        ClickList: TStrings; { declare the field }
      end;
    var
      Form1: TForm1;
    implementation
    {$R *.DFM}
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      ClickList := TStringList.Create; { construct the list }
    end;
    procedure TForm1.FormDestroy(Sender: TObject);
    begin
      ClickList.SaveToFile(ChangeFileExt(Application.ExeName, '.LOG')); { save the list }  ClickList.Free; { destroy the list object }
    end;
    procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      ClickList.Add(Format('Click at (%d, %d)', [X, Y])); { add a string to the list }
    end;
    end.
      

  3.   

    TStrings是一个抽象类.得在子类中实现抽象函数后才能正常使用.楼主看Delphi类库里的StdCtrls.pas的2167行constructor TCustomMemo.Create(AOwner: TComponent);
    begin
      inherited Create(AOwner);
      Width := 185;
      Height := 89;
      AutoSize := False;
      FWordWrap := True;
      FWantReturns := True;
      FLines := TMemoStrings.Create;//这个就是FLines对象的创建;
      TMemoStrings(FLines).Memo := Self;
      ParentBackground := False;
    end;1249行是TMemoStrings的定义;
      TMemoStrings = class(TStrings)
      private
        Memo: TCustomMemo;
      protected
        function Get(Index: Integer): string; override;
        function GetCount: Integer; override;
        function GetTextStr: string; override;
        procedure Put(Index: Integer; const S: string); override;
        procedure SetTextStr(const Value: string); override;
        procedure SetUpdateState(Updating: Boolean); override;
      public
        procedure Clear; override;
        procedure Delete(Index: Integer); override;
        procedure Insert(Index: Integer; const S: string); override;
      end;
    在这个类里实现它的父类的所有抽象函数这样TStrings对象就可以使用了.Tstrings类的loadfromfile函数虽然不是抽象函数,但楼主可以仔细看看这个方法的实现.
    procedure TStrings.LoadFromFile(const FileName: string);
    var
      Stream: TStream;
    begin
      Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
      try
        LoadFromStream(Stream);//使用了LoadFromStream函数;
      finally
        Stream.Free;
      end;
    end;再看LoadFromStream函数;procedure TStrings.LoadFromStream(Stream: TStream);
    var
      Size: Integer;
      S: string;
    begin
      BeginUpdate;
      try
        Size := Stream.Size - Stream.Position;
        SetString(S, nil, Size);
        Stream.Read(Pointer(S)^, Size);
        SetTextStr(S);//使用了SetTextStr函数
      finally
        EndUpdate;
      end;
    end;再看SetTextStr函数;procedure TStrings.SetTextStr(const Value: string);
    var
      P, Start: PChar;
      S: string;
    begin
      BeginUpdate;
      try
        Clear;
        P := Pointer(Value);
        if P <> nil then
          while P^ <> #0 do
          begin
            Start := P;
            while not (P^ in [#0, #10, #13]) do Inc(P);
            SetString(S, Start, P - Start);
            Add(S);//使用了ADD函数;
            if P^ = #13 then Inc(P);
            if P^ = #10 then Inc(P);
          end;
      finally
        EndUpdate;
      end;
    end;再看Add函数;function TStrings.Add(const S: string): Integer;
    begin
      Result := GetCount;
      Insert(Result, S);//使用了Insert函数;
    end;再来看Insert函数你会发现这个函数只有定义没有实现..看看Insert函数的定义
    procedure Insert(Index: Integer; const S: string); virtual; abstract;
    是一个抽象函数吧; *^_^*