self,指的是实例对象的指针吗?他是什么类型的变量,存储在什么位置!
例如TForm1类,在TForm1类的OnClose事件中有以下语句procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
//Action:=cafree;
self.Free;
self:=nil;
end;创建该类型的两个实例frm1和frm2,关闭frm1后,是否frm1的内存已经释放?(应该是释放了),
self:=nil 该如何理解?这句代码有什么作用吗?执行这句代码后,为何frm1跟frm2都<>nil,那么到底是谁=nil了?还是这句代码本身就有问题?
例如TForm1类,在TForm1类的OnClose事件中有以下语句procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
//Action:=cafree;
self.Free;
self:=nil;
end;创建该类型的两个实例frm1和frm2,关闭frm1后,是否frm1的内存已经释放?(应该是释放了),
self:=nil 该如何理解?这句代码有什么作用吗?执行这句代码后,为何frm1跟frm2都<>nil,那么到底是谁=nil了?还是这句代码本身就有问题?
解决方案 »
- 右下角的CSDN推荐真TM恶心
- 怎么知道调用某个函数的上级过程的名称
- 仿效flashget的悬浮窗口,可是在任务管理器中却有两个进程,?为什么啊?进来看看我的代码!
- 高分求网络扑克牌源码或思路
- 菜鸟问题一个:验证窗体(普通)、主窗体(MDI)、子窗体1(MDICHILD1) 启动顺序问题!分不够另开贴再加!!!!
- 小妹刚学delphi不久,有个combobox的小问题请教各位高手!!在线等!...
- 请问,从函数或过程的定义跳到实现部分的快捷键是什么?
- 怎样为DBGRID加上背景图啊?急!!在线等待
- 请教一下关于数据库录入界面的做法
- 十万火急,help me!!!
- 如何中止循环?
- DBGrid ,ADOQuery 相关
self.free;为释放对象
self:=nil;为将对象地址值空。“free;是把你的房子拆了,:=nil是把记录你住址的记录清空”,不怎么会表达这个。type test= class
private
a:string;
procedure tt();
end;
implementation{$R *.dfm}
procedure test.tt();
begin
Self.a := 'xxx';
end;应该说是当前类的类型
有意思
--------------------------------------------------
1.self,指的是实例对象的指针吗?
是的2.他是什么类型的变量,存储在什么位置!
他是指向类实例的指针(那个对象调用它,他就指向那个对象),具体存储在内存的什么位置,我还不太清楚,应该是在动态存储区域。3.创建该类型的两个实例frm1和frm2,关闭frm1后,是否frm1的内存已经释放?
已经释放了,因为执行了self.free;语句,但是frm1指针的指向位置并没有变。4.self:=nil 该如何理解?这句代码有什么作用吗?
self可以赋值为nil,但是只要程序走出赋值语句的函数,self就又<>nil了(也可能没走出时self:=nil就无效了)。这句代码没有意义。5.执行这句代码后,为何frm1跟frm2都<>nil,这句话没有意义。
这句话执行不执行,不会影响到frm1跟frm2变量中的指针的值,因为self跟frm1或虽然指向同一实例,但他们二者并不是一个指针, 所以执行这句代码后,frm1跟frm2都<>nil,而只是self=nil了?6.那么到底是谁=nil了?
self:=nil ,只是nil了自己,但是随后self又不等于nil了。7.还是这句代码本身就有问题?
这句代码没有意义,所以不能通过self:=nil 来影响frm1和frm2。补充:
虽然self:=nil没有意义,但是self.free是有意义的,这句代码把self指向的实例的内存给释放了。也就是case5166所说的,住址还在通讯录中写着,但房子被强拆了!这时如果frm1根据通讯录中的地址去找房子是找不到的。
procedure TForm1.btn1Click(Sender: TObject);
begin
self.Caption:='1';
self:=nil;
end;procedure TForm1.btn2Click(Sender: TObject);
begin
self.Caption:='2';
self:=nil;
end;这样依然不会报错//随便点击btn1或btn2都不会报错
procedure TForm1.btn1Click(Sender: TObject);
begin
self:=nil;
self.Caption:='1'; //虽然这句代码没起作用,但是程序没有报错
end;procedure TForm1.btn2Click(Sender: TObject);
begin
self:=nil;
self.Caption:='2'; //虽然这句代码没起作用,但是程序没有报错
end;但是,这样写就报错了procedure TForm1.btn1Click(Sender: TObject);
begin
self:=nil;
self.show; //报非法访问地址错误,所以说self:=nil还是有一定意义的
end;
seleron
(旺旺贝贝)
我是来接分的,当然也随便说几句的
self在过程中一般只是指“窗体”的名称的
self := nil ; //ba form1这个对象的引用 置空 ,类似c中的防止野指针把
此时再引用SELF是错误的
self := nil 意义不大。
form1.free; 虽然此时form1<>nil,但是如果你去访问form1,就会出错。
我一直认为free之后就释放了内存了,nil只是使得指针置空,即使不nil,他所指向的内存已经无效了。
到底是free之后释放内存还是nil之后释放内存?
var
Temp: TObject;
begin
Temp := TObject(Obj);
Pointer(Obj) := nil;
Temp.Free;
end;
看这个引用self在哪个类里边 就是指哪个类
如下这样的类定义type
TMyTest = class
public
procedure Test(AValue: Integer);
end;
mt: TMyTest;Delphi在调用TMyTest的Test方法时,例如mt.Test(1),Delphi编译时,会把这个调用转成
Test(mt, 1)的形式,而Self其实就是对mt的引用,实际上Self在这里只不过是Test方法的一个形参而已,所以,通过Self是可以调用Free方法的,但将Self设为nil,只不过是将一个形参设为nil了,没有什么意义。
而楼主在7楼做的测试,实际上可以转换为SetCaption(nil, '1')这样的形式,虽然程序没有出现明显的异常,但实际上已经出错了,这段程序会将内存起始地址后面的某个位置的值设为'1',只是因为这个地址刚好能够访问,因此,没有报异常而已。
begin
//Action:=cafree;
self.Free;
self:=nil;
end;我这边delphi7的环境,self:=nil直接被优化没了
在一般方法中指的是实例本身,在类方法中指的是类本身2.他是什么类型的变量,存储在什么位置!
指针变量, 存储在栈中EBP - $4,方法被调用时被当做局部变量第一个压栈, 调用时取EAX,因为寄存器更快,形如;
procedure T***.AAA;
var
......
_Self: Pointer;<-- EBP - $4
begin
end;
以下可参看2
(旺旺贝贝)
你的分呀,真是难接呀
这句话不严谨,类方法中的self可能也代表子类,要看这个类方法在哪儿调用的。
type
ta = class
class procedure c;
end;
tb = class(ta)
procedure d;
end;class procedure ta.c;
begin
showmessage(Self.ClassName);
end;procedure tb.d;
begin
c
end;procedure TForm1.FormCreate(Sender: TObject);
var
o: tb;
begin
O := tb.create;
o.d;//显示tb,而不是ta
o.Free
end;2。方法被调用时被当做局部变量第一个压栈
不对,默认是register调用方式,方法被调用时,self被当作第一个参数保存在eax中!并没有压栈!!!
指针 nil 是因为指针指向的内存块已经发生了改变,指过去的时候都不知道指的是什么.
这里 self.free 以后. 再也看不到 self 这个指针了.
self.free以后,他的指针还是存在的。
self代表某个被实例化的类对象,free后,这个对象所占用的内存被回收了,但是此时这个对象的指针并不等于nil,也就是说free后,其指针并没有被置空。