delphi 对象方法的调用

我们编写的方法(或函数)都是一段代码,通过编译后会产生一个入口地址,我们调用该方法,编译形成的汇编码就是 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帮你做好调用.

  另外一个就是我传一个别的对象,可以吧?当然可以!这个方法属于一个对象,但我却传递了另外一个对象的地址,方法可以执行吧.可以,只要那个对象有着和这个对象相同的数据成员,肯定可以正确执行.这时,你应该可以想到什么情况下一个对象有另一个对象的相同的据成员,继承!子类肯定拥用父类相同的数据成员,这也解释了为什么子类可以执行父类的方法,但反过来不一定行得通.

   

   关于对象的方法我能讲的就是这么多,我不是大师,只是说说自己的理解,随手记之,说不定对人有用,以后也可以自己看看. 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值