在 TForm1.Button1Click 函数中,我声明了一个ttest类型的变量,未初始化,但运行成功。希望高手能帮我解释一下,我刚用delphi,谢谢了。(详见代码)
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TTest = class;
TTest = class(TObject)
public
i: integer;
procedure test;
constructor Create;
end; 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
test1: TTest;
begin
// 未初始化,为什么可以继续执行。
// test1 := TTest.Create;
test1.test;
test1.i :=5;
showmessage(inttostr(test1.i));
end;{ TTest }constructor TTest.Create;
begin
// abort;
end;procedure TTest.test;
begin
showmessage('hello, world!');
end;end.我很奇怪,为什么不初始化也能运行???????经过试验,我得出如下结论,请指教如果不初始化,delphi也会分配一块内存,不过此内存是只读的。
1. 当test类中有成员变量字段时,如果对成员变量赋值,退出程序时才会报错。报内存只读错误。如果有成员变量,但没有赋值,也不会报错。2. 如果当test类中没有成员变量字段,可以正常运行,且不报错。3. 如果test类型的变量声明成临时变量与全局变量,其分配内存的方式是不一样的。全局变量,不为类中的字段变量分配内存。临时变量,为类中的字段变量分配内存,不过是只读的,但在赋值时不会出错,在退出程序时才报错。各位高手验证一下我得出的结论,看看对不对。也请帮我详细解释一下delphi的内存分配机制。为什么不分配内存也可以执行方法?为什么不报错?
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TTest = class;
TTest = class(TObject)
public
i: integer;
procedure test;
constructor Create;
end; 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
test1: TTest;
begin
// 未初始化,为什么可以继续执行。
// test1 := TTest.Create;
test1.test;
test1.i :=5;
showmessage(inttostr(test1.i));
end;{ TTest }constructor TTest.Create;
begin
// abort;
end;procedure TTest.test;
begin
showmessage('hello, world!');
end;end.我很奇怪,为什么不初始化也能运行???????经过试验,我得出如下结论,请指教如果不初始化,delphi也会分配一块内存,不过此内存是只读的。
1. 当test类中有成员变量字段时,如果对成员变量赋值,退出程序时才会报错。报内存只读错误。如果有成员变量,但没有赋值,也不会报错。2. 如果当test类中没有成员变量字段,可以正常运行,且不报错。3. 如果test类型的变量声明成临时变量与全局变量,其分配内存的方式是不一样的。全局变量,不为类中的字段变量分配内存。临时变量,为类中的字段变量分配内存,不过是只读的,但在赋值时不会出错,在退出程序时才报错。各位高手验证一下我得出的结论,看看对不对。也请帮我详细解释一下delphi的内存分配机制。为什么不分配内存也可以执行方法?为什么不报错?
宠辱不惊,看庭前花开花落,去留无意;毁誉由人,望天上云卷云舒,聚散任风。
————————————————————————————————————
TTest = class(TObject)本身就有了ttest.oncreate事件了
thx,
请问,如果没有TTest.Create; 那这个对象的生命期应该怎么控制。
我对button1click事件作如下修改
procedure TForm1.Button1Click(Sender: TObject);
var
test1: TTest;
begin
// 未初始化,为什么可以继续执行。
// test1 := TTest.Create;
test1.test;
// test1.i :=5;
// showmessage(inttostr(test1.i));
// 添加了代码
test1.free;
end;
其结果是............. button1从界面消失了, 为什么???????
为什么我用test1.free 会把button给释放掉???
是不是很类似?看看风炎的回答
procedure TForm1.Button1Click(Sender: TObject);
var
test1: TTest; //编译器对这个申明语句的解释就是开辟第一个空间,此时第二空间不存在,而第三空间在编译器碰到上面的类申明的时候就已经分配了!所以存在!
begin
//test1 := TTest.Create;----本应该编译器看到这个句子才开始开辟第二空间,但由于你注释掉了,所以程序中根本没有第二空间,所以test1只是一个野指针!
test1.test; //虽然没有第二空间,但编译器仍然可以进入第三空间查找方法入口地址,所以这里可以调用成功;但这里存在一个问题,由于我们前面说了三个空间组成一个链,而在断链的情况下编译器仍能顺利进入第三空间进行方法的查找,我唯一可以想到的就是只有通过RTTI信息进行这种定位了,有待讨论!
test1.i :=5; //第二空间不存在,所以内存错误
showmessage(inttostr(test1.i)); //同上道理
end;
另外AD,我们上次讨论的那个问题根本就没有讨论清楚,至于风焱的解答我认为和讨论的问题没有多大关系!
procedure TForm1.Button1Click(Sender: TObject);
var
test1: TTest; //编译器对这个申明语句的解释就是开辟第一个空间,此时第二空间不存在,而第三空间在编译器碰到上面的类申明的时候就已经分配了!所以存在!
begin
//test1 := TTest.Create;----本应该编译器看到这个句子才开始开辟第二空间,但由于你注释掉了,所以程序中根本没有第二空间,所以test1只是一个野指针!
test1.test; //虽然没有第二空间,但编译器仍然可以进入第三空间查找方法入口地址,所以这里可以调用成功;但这里存在一个问题,由于我们前面说了三个空间组成一个链,而在断链的情况下编译器仍能顺利进入第三空间进行方法的查找,我唯一可以想到的就是只有通过RTTI信息进行这种定位了,有待讨论!
test1.i :=5; //第二空间不存在,所以内存错误
showmessage(inttostr(test1.i)); //同上道理
end;
另外AD,我们上次讨论的那个问题根本就没有讨论清楚,至于风焱的解答我认为和讨论的问题没有多大关系!
test dl,dl
jz +$08
add esp,-$10
call @ClassCreate //在这里将调用System.pas单元中的函数_ClassCreate(申明在1348行,实现在9018行,参考D7),并且使用这个函数来为对象在栈上分配实际的内存空间。所以说对象到了这个时候才真正地存在于系统为你的程序创建的进程空间的栈上。因此,如果没有调用Create构造器,我们通过Var申明的对象(指针)只是一个内容为初始化内容的指针,其内容是没有实际意义的。所以这里调用访问私有数据的OP语句是报内存错误!------------------------------------------------------------------------希望对各位有帮助!同时留下一个问题:为什么在不调用Create构造器的情况下,编译器仍然可以通过一个简单的对象指针来进入到正确的类VMT中寻找方法入口地址,中间的过程是如何实现的?希望各位讨论...........
鄙视啊
抄也要知道原理,况且这个代码《Mastering Delphi 4》上就有!而且比这个还多,你要不要啊?我给你介绍的几本书你能认真的理解就不错了,怕的就是你买了那些书而不去认真看,最后还不如不买,永远都是知其然不知其所以然!
http://expert.csdn.net/Expert/topic/2185/2185503.xml?temp=.5702783
接分,