delphi 对象方法的调用
2012-12-16 23:32
176 查看
我们编写的方法(或函数)都是一段代码,通过编译后会产生一个入口地址,我们调用该方法,编译形成的汇编码就是 call func的形式,func就是函数名,标识着这个入口地址,无非是告诉cpu jmp到这个地址取指令,运行
对象的方法一样得符合这个法则,我们编写一个类:如
TA=Class
proceudre Func(...);//方法原形;
end
Procedure TA.Func(...) //方法实现的地方,静态编译后,调入内存运行时,会产生一个入口地址.
begin
....
end;
TA.func就标识着这个地址 你可以通过@TA.func取得这个方法的地址,这和一般的方法一样,都只是内存当中的一个地址而已,编译器并没有因为它是一个对象的方法而特别的对待,即然如此,我们当然也可以当这个方法如一般方法一样的调用,你在程序当中写下如此:
begin
asm
call TA.func.
end
end
如此调用完全可以成立,甚至完全可以运行,只是有一些风险(这个跟你函数代码内容有关).
的确大多数资料都这样写着:对象的方法只能通过对象调用,想当初,我也是这么毕恭毕敬的遵守着这样的条列,完全没有去想想背后到底是个什么原理,还有的资料写着:当基类继承父类后,它就继承了父类的数据成员和方法,我一时也没想明白:方法可以继承?方法是怎么继承的?我一时也弄不清这话是从哪个角度来考量的.
一个很好的方法就是查看Cpu的汇编码,通过汇编码幕后的东西暴露无遗.
var obj:TA
obj.func(...),这就是标准的对象方法调用,我们查看汇编,一般会看到如下形式:
mov EAX,[OBJ];将obj对象的地址,送入了EAX..
Call TA.Func;//调用那个静态编译后的方法,这和调用一般方法没啥两样...
唯一不同的是,对象地址被送入了EAX寄存器,这是干什么?delphi默认的函数调用惯例是寄存器调用惯例,用寄存器来传递参数!也就是说将obj对象当作一个参数一样传递了,这就是对象方法调用的惯例:对象当作参数传,然后就调用那个TA.FUNC,就这么简单.
我们平常说的对象方法内部那个self指针就是这个参数,传对象是有理由的:毕竟是对象方法,内部要能访问对象的数据成员或其它什么东西,但对象的数据成员在另一个块内存上,你不传递这个内存的地址,怎么能定位到它的数据成员?如果传递一个对象的地址(对象就代表着那块内存的地址),万事ok..
但有一些小小的有趣的东西总是存在:你看着第一步,将对象做为参数传递,参数么?我想传啥就啥,确实你
mov eax,0,电脑也拿你也没办法.问题是我不传一个对象,该方法可以执行吧?有时候行,有时候不行,当你的对象方法,没有用到对象任何的数据成员或其它东西,肯定能执行.这时你肯定会想到类方法,就是这么回事,类方法当中就是不能访问对象的成员.为你省事,delphi帮你做好调用.
另外一个就是我传一个别的对象,可以吧?当然可以!这个方法属于一个对象,但我却传递了另外一个对象的地址,方法可以执行吧.可以,只要那个对象有着和这个对象相同的数据成员,肯定可以正确执行.这时,你应该可以想到什么情况下一个对象有另一个对象的相同的据成员,继承!子类肯定拥用父类相同的数据成员,这也解释了为什么子类可以执行父类的方法,但反过来不一定行得通.
关于对象的方法我能讲的就是这么多,我不是大师,只是说说自己的理解,随手记之,说不定对人有用,以后也可以自己看看.
对象的方法一样得符合这个法则,我们编写一个类:如
TA=Class
proceudre Func(...);//方法原形;
end
Procedure TA.Func(...) //方法实现的地方,静态编译后,调入内存运行时,会产生一个入口地址.
begin
....
end;
TA.func就标识着这个地址 你可以通过@TA.func取得这个方法的地址,这和一般的方法一样,都只是内存当中的一个地址而已,编译器并没有因为它是一个对象的方法而特别的对待,即然如此,我们当然也可以当这个方法如一般方法一样的调用,你在程序当中写下如此:
begin
asm
call TA.func.
end
end
如此调用完全可以成立,甚至完全可以运行,只是有一些风险(这个跟你函数代码内容有关).
的确大多数资料都这样写着:对象的方法只能通过对象调用,想当初,我也是这么毕恭毕敬的遵守着这样的条列,完全没有去想想背后到底是个什么原理,还有的资料写着:当基类继承父类后,它就继承了父类的数据成员和方法,我一时也没想明白:方法可以继承?方法是怎么继承的?我一时也弄不清这话是从哪个角度来考量的.
一个很好的方法就是查看Cpu的汇编码,通过汇编码幕后的东西暴露无遗.
var obj:TA
obj.func(...),这就是标准的对象方法调用,我们查看汇编,一般会看到如下形式:
mov EAX,[OBJ];将obj对象的地址,送入了EAX..
Call TA.Func;//调用那个静态编译后的方法,这和调用一般方法没啥两样...
唯一不同的是,对象地址被送入了EAX寄存器,这是干什么?delphi默认的函数调用惯例是寄存器调用惯例,用寄存器来传递参数!也就是说将obj对象当作一个参数一样传递了,这就是对象方法调用的惯例:对象当作参数传,然后就调用那个TA.FUNC,就这么简单.
我们平常说的对象方法内部那个self指针就是这个参数,传对象是有理由的:毕竟是对象方法,内部要能访问对象的数据成员或其它什么东西,但对象的数据成员在另一个块内存上,你不传递这个内存的地址,怎么能定位到它的数据成员?如果传递一个对象的地址(对象就代表着那块内存的地址),万事ok..
但有一些小小的有趣的东西总是存在:你看着第一步,将对象做为参数传递,参数么?我想传啥就啥,确实你
mov eax,0,电脑也拿你也没办法.问题是我不传一个对象,该方法可以执行吧?有时候行,有时候不行,当你的对象方法,没有用到对象任何的数据成员或其它东西,肯定能执行.这时你肯定会想到类方法,就是这么回事,类方法当中就是不能访问对象的成员.为你省事,delphi帮你做好调用.
另外一个就是我传一个别的对象,可以吧?当然可以!这个方法属于一个对象,但我却传递了另外一个对象的地址,方法可以执行吧.可以,只要那个对象有着和这个对象相同的数据成员,肯定可以正确执行.这时,你应该可以想到什么情况下一个对象有另一个对象的相同的据成员,继承!子类肯定拥用父类相同的数据成员,这也解释了为什么子类可以执行父类的方法,但反过来不一定行得通.
关于对象的方法我能讲的就是这么多,我不是大师,只是说说自己的理解,随手记之,说不定对人有用,以后也可以自己看看.
相关文章推荐
- Delphi动态事件深入分析(对象方法在调用的时候会传递一个隐含的Self指针,而该指针的值在EAX中。即左边第一个参数)
- 关于子类创 4000 建对象调用父类方法时this的问题(以及方法重写)
- 关于java调用对象,方法的注意事项
- java在调用System.out.println()打印一个新new的对象时,为什么会调用toString方法?
- OC多文件开发简单例子实现(重点:self在对象方法中调用其他对象方法的3种方法)
- 理解 Delphi 的类(十一) - 深入类中的方法[13] - 方法的调用约定
- 修改window.external使JavaScript可以调用Delphi内定义的方法
- 兼容IE和火狐JS父窗口调用iframe里面的对象、函数的方法
- 当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的内容可以在被调用的方法中改变,但对象的引用是永远不会改变的.
- Ajax调用后类方法时报”对象未定义“错误解决方法
- [JNI]开发之旅(7)JNI函数中调用java对象的方法
- php面向对象中static静态属性和静态方法的调用
- 《GOF设计模式》—工厂方法(Factory Method)—Delphi源码示例:延迟初始化对象
- 实例化Transform对象与GameObject对象时调用方法时的区别
- JAVA中申请了两个对象,分别在调用方法和声明方法中把其中一个对象直接赋值给另外一个对象,运行结果,求原理。
- Delphi中的DLL封装和调用对象编写碰到的问题
- 关于jsp 的对象response调用sendRedirect方法,是否用return
- 8.python之面相对象part.5(子类调用父类的方法,以及super关键字)
- Delphi中主窗体的formshow事件在程序自动创建窗体对象前就调用的错误。
- HashSet 中储存先判断对象的hash值 如果一样 在调用 对象equals方法判断是否是同一个对象