首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > .NET >

从一个控件BUG想到的:怎么判断类未被初始化

2012-03-08 
从一个控件BUG想到的:如何判断类未被初始化!typepp1classprivatei:Tbuttonend........................

从一个控件BUG想到的:如何判断类未被初始化!
type
    pp1   =   class  
    private
        i:   Tbutton;
end   ;
........
........
........

procedure   TForm1.Button1Click(Sender:   TObject);
var   pp2:   pp1   ;
begin
    if   (pp2 <> nil)   and   (Assigned(pp2))   then     //   因为这个判断不对!!!!!!!!!!!
    begin
        showmessage( 'Not   nil ')   ;
        pp2.i   :=   TButton.Create(Form1);               //   这个建立在未知内存区,所以窗体关闭时,有AV内存溢出的错误
    end   ;
end;

不知道如何判断这个新类未被新建!




[解决办法]
从常规方法来讲应该是没有办法判断的。
一般用ASSIGNED来判断有个前提就是该对象在释放的时候是使用FreeAndNil来做才行,也就是要进行ps := nil;这个才能确保。
[解决办法]
偏题说一下:(个人看法,可能说得不对)

楼主的代码中有许多不够严谨的地方....

例如:在TForm1类里访问pp1类的私有成员;pp1类继承自TObject,却拥有一个TButton类的成员;var pp2: pp1 ;这句易令人误解。
[解决办法]
看...果然我说错了...
[解决办法]
呵!

那我言归正传给楼主讲一下,看楼主是否满意:

1、你不必用一个自定义类来试验的,你完全可以用一个普通的VCL类,例如一个TEdit

请比较一下:

代码一:

var
E : TEdit;

procedure TForm1.Button2Click(Sender: TObject);
begin
if not Assigned(E) then
begin
E := TEdit.Create(self);
E.Parent := self;
end;
end;



代码二:

procedure TForm1.Button2Click(Sender: TObject);
var
E : TEdit;
begin
if not Assigned(E) then
begin
E := TEdit.Create(self);
E.Parent := self;
end;
end;

运行之后,有何不同?

-------因为:局部指针变量不会被初始化为nil,只是被指向了一个随机的地址;而全局指针变量却被初始化为nil--------这就是为什么局部变量声明后立即用not Assigned(P)或 if P <> nil无效的原因!


2、pp2.i := TButton.Create(Form1); // 这个建立在未知内存区,所以窗体关闭时,有AV内存溢出的错误
这样用,本身就是不对的,原因我在二楼已说,现不多言。
[解决办法]
关于 1 ,多言一句:

一个程序占用的内存,大体可分为:代码区、全局数据区、堆、栈。

全局数据被application分配在“全局数据区”,并初始化它;
局部变量被动态地在“堆”内存分配,不初始化,而从堆里分配的内存,极可能是刚刚被释放的,仍保留着前面用过的数据......
[解决办法]
不要把Assigned(x)当宝!它只是判断 x是否为nil!

Tests for a nil (unassigned) pointer or procedural variable.

Unit

System

Category

miscellaneous routines

function Assigned(var P): Boolean;

Description

Use Assigned to determine whether the pointer or procedure referenced by P is nil.
[解决办法]
如果要判断一个对象变量是否被赋值,请一开始给这个变量初始化为 nil.
[解决办法]
顺便说一下,这里不存在什么BUG。如果你把这个看作BUG,那是你的BUG了。
[解决办法]
高人 学习了
[解决办法]
TButton.Create(Form1);
这个应该写成 TButton.Create(Self);
按钮在构造时候,指明物主为当前窗体,在窗体销毁时,会自动销毁该按钮。这个可以参阅 TComponent源代码.
------解决方案--------------------


jf~

热点排行