究竟用什么判断对象已存在?(50分)

  • 主题发起人 主题发起人 hthugm
  • 开始时间 开始时间
呵呵,你不是自己说了吗.X是一个指针,实际只占32位空间.
当你没有对它赋植的时候,由于它是局部变量,所以随机的指向了一个地址,而不一定是nil。
当你用合法的赋值语句附值,Ok,现在它指向了一个对象。
当这个局部变量指针离开作用域,它被自动释放。如果你先前没有
调用Free方法释放对象,那么它原来指向的对象可能仍然存在,这样有可能造成内存泄露.
 
兄弟,我以前问过这个问题:
局部变量会自动赋给一个随机值,所以,Assigned返回True(你是不是认为应该返回False呀?),
如果是全局变量,默认为nil阿! 所以有人说:"你不会连变量的作用域都不知道吧!"
我的问题在:http://www.delphibbs.com/delphibbs/dispq.asp?lid=1499819
 
to 上面的朋友们:
首先谢谢你们;

我是本意是这样的

我从串口取回一些数据我将这些数据解析后,将结果显示在另外一个窗体上,这个窗体我
是动态生成的,
所以我的X:TForm2肯定是局部变量,我为什么要用全局变量呢?现在用户没有关闭这个窗体
又从串口取回一些数据现要重新显示,因
X:=NIL这一句肯定是在if Not AsSigned(X)的前面,现在我的窗体没有关闭,
X:=Nil还需要吗([red]没有关闭这个窗体),[/red]但如果没有这一条语句哪第一次就显示结果时就出问题,
如果用全局变量可以解决。但不知朋友们是否写过大型程序没有,我这个无用的窗体
(除了显示结果外它再没有其它作用)还需要用全局吗?这不浪费资源吗。
请高手继续指教。
 
hthugm兄啊。你究竟是怎么理解动态创建的啊?
就按你的意思吧,你的X声明成局部的,又怎样啊?节省资源啦?
这是当然的,因为你的代码一离开当前的函数,X是被自动释放了的,的的确确是节省资源
了,但是你要的东西呢?没了。。:(

楼上已经有不少的兄弟为你指正,你的意识上,没有把全局和局部的概念弄清,
我说啊,,是不是hthugm兄你,把这事当得太过神圣了啊?本来就是这么简单的事,结果
你就是不信,,:(
其实你再看看,,N个动态创建对象的过程,如果要还要离开这个函数做操作这个动态的对象
的话,,那是肯定不能够定义函数内可用的局部变量的。
如果你硬要把动态创建理解成你这目前这种动态性,,那我看大伙都没有辙。

一般地,你在创建一个新的窗体时,在这个窗体的单元文件里,会自动为你生成一个
跟你的窗体类名接近的全局变量,比如你的窗体类名是: TFormMain, 那在这个窗体的单元
文件中就有一个 FormMain 的全局变量被声明在 interface 部分的。

一般情况下我是这样子动态管理这个 Formmain 的。

begin
if not Assigned(FormMain) then
FormMain := TFormMain.Create(Application);
...// To-do something..
end;

你觉得这样子不好吗?
 
你改成怎么样判断一个窗体吧,或是一个控件!
我也不知道。
 
TO DARNIS:
你的代码一离开当前的函数,X是被自动释放了的,的的确确是节省资源
了,但是你要的东西呢?没了。。:

什么意思我要的东西已经显示出来了,用户已看了而且窗体还没有关闭,
显示在这个窗体上的EDIT上的东西因我的代码一离开当前的函数,X是被自动释放了
它会变得没有吗,你这是哪里来的DELPHI,我不明白请指教。

至于你说的
一般地,你在创建一个新的窗体时,在这个窗体的单元文件里,会自动为你生成一个
跟你的窗体类名接近的全局变量,比如你的窗体类名是: TFormMain, 那在这个窗体的单元
文件中就有一个 FormMain 的全局变量被声明在 interface 部分的。
看来你还没有做过程序,做程序的人一般会把
“文件中就有一个 FormMain 的全局变量被声明在 interface 部分的”中的变量删除
至于原因我建议你好好看一下书,你是研究生吗!!!!
 
to hthugm:
从你的提问开始,程序运行的结果是'x is existed',为什么呢?
运行程序时在begin处设置断点,当执行到断点时,按ctrl+alt+c打开cpu窗口,你会发现
if Not AsSigned(x) then这条语句对应两条汇编语句
1.test ebx,ebx
2.jnz +$2f。
第一句其实就是实现assigned(x)的功能,它检测x是否为空,然后将结果反映到标志寄
存器中,第二句是一个条件跳转语句,它根据上一句test ebx,ebx对标志寄存器的影响来
实现跳转,也就是实现if...then...的功能,在此就能看出来了,x的值根本不在内存中,
而在ebx这个32位的寄存器中!!!也就是说假如此时ebx的值为nil,
执行ShowMessage('x is not existed');不为空则执行ShowMessage('x is existed')。
大多数情况下ebx此时不会为nil,所以就执行了ShowMessage('x is existed')。
如果把代码改成
procedure TForm1.Button1Click(Sender: TObject);
var
x:Tedit;
begin

asm
mov ebx,$0 ///将ebx置nil
end;

if Not AsSigned(x) then
begin
x:=Tedit.create(self);
x.parent:=self;
x.visible:=True;
ShowMessage('x is not existed');
end
else
ShowMessage('x is existed');
end;

运行程序就会执行ShowMessage('x is not existed'),这就证实了上面的说法。
以上说法如有什么不对的地方,恳请高手斧正。
 
这是一个典型的逻辑错误,相信编译器总有一天会把它作为错误提出来的。

下面是详细的回答:
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1294954
(看的时候耐心一些)
 
根本不是什么逻辑错误,只要学过微机原理和汇编的都知道:
计算机是通过压栈、出栈传递参数(dephi默认的Rigister调用还可以利用三个寄存器).
编译器先给你分配一定的栈空间(默认为1M)计算机只不过通过移动栈指针ESP来为参数
和局部变量分配或释放,而其中的数据除刚分配的时候的初始化一次,等调用了多次函数
或过程里面就是些随即数据,编译器是不会替你初始化的。
不信你在C++ 中定义个局部变量不初始化用用看,这东西根本就是和高级语言无关,还讨论些什么??
 
有没有初始化不是你的事情,但是在赋值之前用不用未初始化的变量就是程序员的事情了。

http://www.delphibbs.com/delphibbs/dispq.asp?lid=1294954
看的时候耐心一些,PLEASE
 
局部对象在使用前要赋Nil,这应该是一个良好的编程习惯.
我现在只要用到两个以上的局部对象,必定要先赋空指针.
 
if x=nil then
 
>>我这个无用的窗体(除了显示结果外它再没有其它作用)还需要用全局吗?

是否使用全局变量不是这么判断的。你的问题表面上看是一个临时、局部窗体变量,
但实际上,你要求“如果该窗体已经存在,就使用该窗体“,这样的要求实际上是一个
全局变量。除非你每次都动态创建新的临时窗体。

 
用结构化异常对付
try
obj.free
//使用一个对象的方法或者属性什么的,前提obj<>nil
except
如果出错,那么对象就不存在
end;
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
后退
顶部