这是类的定义:
unit Unit2;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;type
  TA = class(TObject)  private
    { Private declarations }
    FStr: string;
    procedure SetStrValue(Avalue: String);  public
    property Str: String read FStr write SetStrValue;
    { Public declarations }
  end;implementation
{ TA }procedure TA.SetStrValue(Avalue: String);
begin
  if FStr <> AValue then
    FStr := AValue;
end;end.
这是对类的测试:
unit TestClass;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,Unit2, StdCtrls;type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }  public
    { Public declarations }
  end;var
  Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
var
  A,B: TA;
begin
  A := TA.Create;
  B := TA.Create;
  A.Str := 'A';  ShowMessage('A的地址:' +IntToStr(integer(A))+ ' B的地址:' +IntToStr(integer(B)) +' Sender的地址:'+IntToStr(integer(Sender)));
  ShowMessage('A的Str地址:' +IntToStr(integer(@A.Str))+ ' B的Str地址:' +IntToStr(integer(@B.Str)));
  ShowMessage(A.Str);//1.这里显示的是"A"
  ShowMessage(B.Str);//2.这里显示的是空的
  B.Str := 'B';
  ShowMessage(A.Str);//3.这里显示的是"A"
  ShowMessage(B.Str);//4.这里显示的是"B"
  A.Free;
  B.Free;
{
   结果: A的Str地址 和 B的Str地址是不一样的;
   1和2可以证明上面的结果,如果是一样的话;
   安理说2的显示结果应该也为"A";3和4的显示
   应该都为:B在这里我想要说明的问题是:1.我看了有关书籍,是说
在 TA.Create 之前编译器已经为对象分配了内存,不
调用TA.Create 对象一样可以建立,但在上面,如果
我把TA.Create去掉,他就访问不到 A.Str ,这是为什么?
2.如果我把”A := TA.Create“和 "B := TA.Create" 都
去掉,”A的地址“和”Sender的地址"是一样的,但
跟“B的地址”是不一样的,而且“B的地址”只有7位数,而
不是8位了,这是为什么?到底类(TA)的变量"A"和"B"的内存分配
是怎样完成的?}
end;end.

解决方案 »

  1.   

    1、不可能,否则还要Create干嘛。你把TA.create去掉,就没有分配Str内存,当然就访问不到。
    2、把A := TA.Create“和 "B := TA.Create",对象A和B都未创建,A和B的指针都不确定,但我觉得A应该是默认指向窗体。
      

  2.   

    A := TA.Create  //是一定需要的。因为编译器对这句话的翻译是: _ClassCreate;  //为对象分配内存,它确实是在执行用户的Create函数之前分配内存.
                    //可是它的触发需要用户的Create函数。
     A := TA.Create;  //使用用户的Create函数初始化对象
     @AfterConstructor;
      

  3.   

    我自己也跟踪一下!A := TA.Create  在执行到这里确实调用了:_ClassCreate、NewInstance、InstanceSize;
      edgethinking(死鬼) ://可是它的触发需要用户的Create函数。按照这句话来说的话就好理解
    了。”A := TA.Create“和 "B := TA.Create" 都
    去掉,”A的地址“和”Sender的地址"是一样的,A的起始地址跟Sender的起始地址市一样,而且
    能用A.Str :="A";并且显示出来,但当你Close 窗体的时候就访问内存出错了????
      

  4.   

    你把TA = class(TObject)该为TA = class(TForm)试试可以吗?
      

  5.   

    去看《Delphi高手突破》或者《参透Delphi/Kylix》里面有讲
      

  6.   

    楼上的其实我是看《Delphi高手突破》不理解,才发此贴的!其实《Delphi高手突破》
    里面讲的几乎就象: angle097113(深思不解) 所说的了。我就是不太理解这句话,如果
    按: edgethinking(死鬼) 所说的那样好理解,难道是《Delphi高手突破》的作者没有
    说它触发时机吗? 迷惑啊!
      

  7.   

    现在我明白了! 应该确切的说是你的类没有提供构造函数;
    但你在调用Create 构造函数时,编译器一样会为构造对象,只是
    没有初始它的数据成员;但为什么我没有调用Create的时候,它的
    指针跟Sender的一样。