这样的,有一个类  TTest 及这种类型的指针 PTTest,和两个函数如下:prcedure funcA;
var
  t     : TTest;
  test  : TTest;
  pTest : PTTest; 
begin
  //往list及list1中分别加入一个对象和对象的指针
  t := TTest.Create;
  list1.Add(t);
  list2.Add(@t);  //分别取出对象及对象的指针,并调用对象的方法SomeFunc
  test  := TTest(list1.items[0]);
  pTest := PTTest(list2.items[0]);
  test.SomeFunc;
  pTest.SomeFunc;
end;prcedure funcA;
var
  test  : TTest;
  pTest : PTTest; 
begin
  //分别取出对象及对象的指针,并调用对象的方法SomeFunc
  test  := TTest(list1.items[0]);
  pTest := PTTest(list2.items[0]);
  test.SomeFunc;
  pTest.SomeFunc; //出错
end;这两个函数的唯一区别就是FuncA中多执行了一个往队列里加对象的操作,
另我不解的是先调用 FuncA 再调用 FuncB居然会在FuncB的最后一句话出错。
请问这是什么原因?
  

解决方案 »

  1.   

    这样的,有一个类  TTest 及这种类型的指针 PTTest,和两个函数如下:prcedure funcA;
    var
      t     : TTest;
      test  : TTest;
      pTest : PTTest; 
    begin
      //往list及list1中分别加入一个对象和对象的指针
      t := TTest.Create;
      list1.Add(t);
      list2.Add(@t);  //分别取出对象及对象的指针,并调用对象的方法SomeFunc
      test  := TTest(list1.items[0]);
      pTest := PTTest(list2.items[0]);
      test.SomeFunc;
      pTest.SomeFunc;
    end;prcedure funcA;
    var
      test  : TTest;
      pTest : PTTest; 
    begin
      //分别取出对象及对象的指针,并调用对象的方法SomeFunc
      test  := TTest(list1.items[0]);
      pTest := PTTest(list2.items[0]);
      test.SomeFunc;
      pTest.SomeFunc; //出错
    end;这两个函数的唯一区别就是FuncA中多执行了一个往队列里加对象的操作,
    另我不解的是先调用 FuncA 再调用 FuncB居然会在FuncB的最后一句话出错。
    请问这是什么原因?
      

  2.   

    上面的问题中, 下面的那个函数名写错了, 不是FuncA,应该是FuncB
      

  3.   

    我这里没错
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs;type
      tTest = class
      public
       procedure SomeFunc;
      end;
      PTtest = ^TTest;
      TForm1 = class(TForm)
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
      private
        { Private declarations }
      public
        list1: TList;
        list2: TList;    procedure funcA;
        procedure funcB;
      end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.funcA;
    var
      t     : TTest;
      test  : TTest;
      pTest : PTTest;
    begin
      //往list及list1中分别加入一个对象和对象的指针
      t := TTest.Create;
      list1.Add(t);
      list2.Add(@t);  //分别取出对象及对象的指针,并调用对象的方法SomeFunc
      test  := TTest(list1.items[0]);
      pTest := PTTest(list2.items[0]);
      test.SomeFunc;
      pTest.SomeFunc;end;procedure TForm1.funcB;
    var
      test  : TTest;
      pTest : PTTest; 
    begin
      //分别取出对象及对象的指针,并调用对象的方法SomeFunc
      test  := TTest(list1.items[0]);
      pTest := PTTest(list2.items[0]);
      test.SomeFunc;
      pTest.SomeFunc; //出错
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
      list1 := TList.Create;
      List2 := TList.Create;
      funcA;
      funcB;
    end;procedure TForm1.FormDestroy(Sender: TObject);
    begin
      List1.Free;
      List2.Free;
    end;{ tTest }procedure tTest.SomeFunc;
    begin
      ShowMessage('a');
    end;end.
      

  4.   

    1,你执行FUNCA后,在LIST1和LIST2中的ITEM[0]里面存放的都应该是已经被释放的对象,因为FUNCA执行结束后,你ADD的T和@T就已经释放了;
      

  5.   

    outer2000(天外流星)  在FUNCB中,取出的对象可以正确的调用其成员。为何取出来的指针不能正确调用其成员呀。
      

  6.   

    To  outer2000(天外流星) ( )    没有释放,要是值类型才会被释放
      

  7.   

    是呀,我建议改成 
    unit Unit1;
    interface
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs;
    type
      tTest = class
      public
       procedure SomeFunc;
      end;
      PTtest = ^TTest;
      TForm1 = class(TForm)
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
      private
        { Private declarations }
      public
        list1: TList;
        list2: TList;    procedure funcA;
        procedure funcB;
      end;var
      Form1: TForm1;implementation
    var
      t     : TTest;
    {$R *.dfm}procedure TForm1.funcA;
    var 
      test  : TTest;
      pTest : PTTest;
    begin
      //往list及list1中分别加入一个对象和对象的指针
      t := TTest.Create;
      list1.Add(t);
      list2.Add(@t);  //分别取出对象及对象的指针,并调用对象的方法SomeFunc
      test  := TTest(list1.items[0]);
      pTest := PTTest(list2.items[0]);
      test.SomeFunc;
      pTest.SomeFunc;end;procedure TForm1.funcB;
    var
      test  : TTest;
      pTest : PTTest; 
    begin
      //分别取出对象及对象的指针,并调用对象的方法SomeFunc
      test  := TTest(list1.items[0]);
      pTest := PTTest(list2.items[0]);
      test.SomeFunc;
      pTest.SomeFunc; //出错
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
      list1 := TList.Create;
      List2 := TList.Create;
      funcA;
      funcB;
    end;procedure TForm1.FormDestroy(Sender: TObject);
    begin
      List1.Free;
      List2.Free;
      t.Free;
    end;{ tTest }procedure tTest.SomeFunc;
    begin
      ShowMessage('a');
    end;end.
      

  8.   

    palluo(palzhou):
       你贴出来的代码是没有错的,除非List2.items[0]的内容改变了,或者是对象被释放了   建议你检查一下其他的地方
      

  9.   

    FUNCB--->TLIST2 has no initliazed. then pTest := PTTest(list2.items[0]) pointed to a noaddress or 'a bad' address.
      

  10.   

    这是所有的代码,请大伙过目:nit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs;type  pTBase = ^TBase;
      PTTest = ^TTest;  TBase = class
      public
        procedure SomeFunc; virtual;
      end;  TTest = class(TBase)
      public
       procedure SomeFunc; override;
      end;  TForm1 = class(TForm)
        procedure FormCreate(Sender: TObject);
      private
        list1 : TList;
        list2 : TList;    procedure funcA;
        procedure funcB;
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.FormCreate(Sender: TObject);
    begin
      list1 := TList.Create;
      List2 := TList.Create;
      funcA;
      funcB;
    end;procedure tBase.SomeFunc;
    begin
      ShowMessage('base');
    end;procedure tTest.SomeFunc;
    begin
      ShowMessage('test');
    end;procedure TForm1.funcA;
    var
      t     : TTest;
      test  : TBase;
      pTest : PTBase;
    begin
      //往list及list1中分别加入一个对象和对象的指针
      t := TTest.Create;
      list1.Add(t);
      list2.Add(@t);  //分别取出对象及对象的指针,并调用对象的方法SomeFunc
      test  := TBase(list1.items[0]);
      pTest := PTBase(list2.items[0]);
      test.SomeFunc;
      pTest.SomeFunc;end;procedure TForm1.funcB;
    var
      test  : TBase;
      pTest : PTBase;
    begin
      //分别取出对象及对象的指针,并调用对象的方法SomeFunc
      test  := TBase(list1.items[0]);
      pTest := PTBase(list2.items[0]);
      test.SomeFunc;
      pTest.SomeFunc; //出错
    end;
    end.
      

  11.   

    LIST里的东西被释放了;一定是;指针又如何?
      

  12.   

    我明白了t所指向的对象没有被释放       但是t自己作为一个局部变量已经被释放了 存入的是@t,出了funcA找不到了不知道这样说清不清楚
      

  13.   

    关键是在FUNCB中,取出的对象可用,而取出的指针却不能用,这是为什么?
      

  14.   

    我知道原因了,和 rustle(一日不过三) 说的差不多吧。
    我是这样理解的:t 是一个局部变量,FUNCA执行完全将释放。也就是@t在函数退出时将变成无效地址,所以在FUNCB中取出的这个地址当然会出错。在FUNCB中取出对象不会错是因为TLIST类在ADD函数里会重新构造一个和要加入对象一样的东西,所以t的释放不会影响到它。好了,谢谢大伙的关心,散分!!!!!!!!