Delphi - 对象构造浅析后续
技术交流,DH讲解.
之前一篇文章已经讲过对象构造的过程,但是我们那个对象无任何东西,这里我们在已有的基础上面加点儿东西再来看看.
代码改成:
THuangJacky = classprivateFName:string;publicprocedure SayMyName();constructor Create();end;varForm3: TForm3;implementation{$R *.dfm}procedure TForm3.btn1Click(Sender: TObject);
varA:THuangJacky;
beginA:=THuangJacky.Create;A.Free;
end;{ THuangJacky }constructor THuangJacky.Create;
beginFName:='HuangJacky';
end;procedure THuangJacky.SayMyName;
beginShowMessage(FName);
end;
我们可以看到多了一个私有域和公有方法.
构造过程:
utMain.pas.38: A:=THuangJacky.Create;
004B33E4 B201 mov dl,$01
004B33E6 A1C8324B00 mov eax,[$004b32c8] //类地址都变化了.
004B33EB E808000000 call THuangJacky.Create
utMain.pas.45: begin
004B33F8 53 push ebx
004B33F9 56 push esi
004B33FA 84D2 test dl,dl
004B33FC 7408 jz $004b3406
004B33FE 83C4F0 add esp,-$10
004B3401 E8D61EF5FF call @ClassCreate //前面都一样,又是调用这个参数,但是我们知道eax参数(类地址)变化了
004B3406 8BDA mov ebx,edx
004B3408 8BF0 mov esi,eax
utMain.pas.46: FName:='HuangJacky';
004B340A 8D4604 lea eax,[esi+$04]
004B340D BA40344B00 mov edx,$004b3440
004B3412 E82D34F5FF call @UStrAsg
我们可以看到是先构造然后赋值字符串的,@ClassCreate之前的判断都一样的,我们看看$004b3440 地址的数据:
不要忘了我是在D2010下面,所以是Unicode字符串.
@ClassCreate:
004052DC 52 push edx
004052DD 51 push ecx
004052DE 53 push ebx
004052DF 84D2 test dl,dl
004052E1 7C03 jl $004052e6
004052E3 FF50F4 call dword ptr [eax-$0c]
004052E6 31D2 xor edx,edx
004052E8 8D4C2410 lea ecx,[esp+$10]
004052EC 648B1A mov ebx,fs:[edx]
004052EF 8919 mov [ecx],ebx
004052F1 896908 mov [ecx+$08],ebp
004052F4 C7410405534000 mov [ecx+$04],$00405305
004052FB 89410C mov [ecx+$0c],eax
004052FE 64890A mov fs:[edx],ecx
00405301 5B pop ebx
00405302 59 pop ecx
00405303 5A pop edx
00405304 C3 ret
这个函数还是一样的.我们不需要看了,从这里跳吧004052E3
TObject.NewInstance:
00404D40 53 push ebx
00404D41 8BD8 mov ebx,eax
00404D43 8BC3 mov eax,ebx
00404D45 E826000000 call TObject.InstanceSize
00404D4A E885F4FFFF call @GetMem
00404D4F 8BD0 mov edx,eax
00404D51 8BC3 mov eax,ebx
00404D53 E85C000000 call TObject.InitInstance
00404D58 5B pop ebx
00404D59 C3 ret
00404D5A 8BC0 mov eax,eax
还是到这里来了,貌似一路上什么都没有变.但是我推想TObject.InstanceSize返回值会有变化,毕竟多了一个私有成员,但是@GetMem肯定不变,TObject.InitInstance也会变化,毕竟有方法了.跟进验证
果然现在TObject.InstanceSize返回值是$0C了,也就是12,上一次什么都没有是8,现在多了4,多了一个指针地址,难道这个指针就是字符串指针一会儿验证下?
接下来我们直接进入InitInstance看看.有什么变化没有?
我跟进去发现没有变化,这个方法不在IntfTable里面的.我们看看初始化完成后的对象数据.
我们看看$004b3320是什么东西.
这里看上去像是THuangJacky的内存地址,那我们最先看见的[$004b32c8]是什么?我们注意地址加上[]就是地址指向的值.
是的,就是指向这里的.
我们让它Create完后再来看对象的数据,OK?
变化了,第二地址会是什么呢?
果然是第一个成员变量的值.
有朋友要问那么SayMyName这个方法的信息存在哪里的呢?这个方法我们要知道是和类挂钩的,所以肯定在类的内存信息块里面的.我们到类信息块去看看,SayMyName字符串前面有4个字节$004B3464
utMain.pas.52: ShowMessage(FName);
004B3464 8B4004 mov eax,[eax+$04]
004B3467 E8AC4CFBFF call ShowMessage
最后来做个试验,我们给类里面再加一个私有成员,然后实现ClassHack,哈哈,违反面向对象的方法
THuangJacky = classstrict private //私有了,访问不了了FName:string;FAge:Integer;publicprocedure SayMyName();procedure SayMyAge();constructor Create();end;varForm3: TForm3;implementation{$R *.dfm}procedure TForm3.btn1Click(Sender: TObject);
varA:THuangJacky;Pi:PInteger;
beginA:=THuangJacky.Create;Pi:=PInteger(Integer(A)+8); //我就要HackShowMessage(IntToStr(Pi^)); //12A.SayMyAge; //12 上面是一样的A.Free;
end;{ THuangJacky }constructor THuangJacky.Create;
beginFName:='HuangJacky';FAge:=12;
end;procedure THuangJacky.SayMyAge;
beginShowMessage(IntToStr(FAge));
end;procedure THuangJacky.SayMyName;
beginShowMessage(FName);
end;
看下新对象的内存和类的内存:
对象的:
类的:
注意看方法前面的地址.哈哈.
今天就说到这里,或许有朋友问这样研究有什么意思.下一篇文章就讲单例模式,这个总有用吧,Delphi里面单例模式就要和我们讲的这些知识挂上钩了,因为Delphi很特别哟.
好,下次见,我是DH.
转载于:https://www.cnblogs.com/huangjacky/archive/2009/12/08/1619438.html
Delphi - 对象构造浅析后续相关推荐
- Delphi - 对象构造和vmt系列
技术交流,DH讲解. 在前面2篇文章中,我们发现在TObject.InitInstance都没有IntfTable,所以有些地方的代码都没有执行. 所以下面我们把代码改一下,看看新的效果,然后把vmt ...
- C# CAD对象 构造时应把它的父对象也加进它的属性里
C# CAD对象 构造时应把它的父对象也加进它的属性里 因为你要根据这一级找它的上一级 转载于:https://www.cnblogs.com/houlinbo/archive/2009/08/2 ...
- 超简易复制Model对象(为后续备忘录设计模式博文做铺垫)
超简易复制Model对象(为后续备忘录设计模式博文做铺垫) 复制整个Model需要实现NSCopy协议,可以想象是非常麻烦的一件事情,今天我跟大家分享一个不需要你做任何操作的复制Model对象的方法, ...
- C++继承体系下的对象构造
继承体系下的对象构造 继承下的对象构造 虚拟继承 初始化"虚基类子对象" vptr的设置 总结 继承下的对象构造 class Point{public:Point(float x ...
- c++无继承情况下的对象构造
无继承情况下的对象构造 C struct的Point声明 在C和C++中有什么区别? 抽象数据类型 包含虚函数的Point声明 自定义构造函数中会安插初始化vptr的代码 以成员为基础的赋值操作 C ...
- c++多个对象构造和析构
多个对象构造和析构 对象初始化列表 对象初始化列表出现原因 注意概念 注意 总结 对象初始化列表 对象初始化列表出现原因 1.必须这样做: 如果我们有一个类成员,它本身是一个类或者是一个结构,而且这个 ...
- $emit传递多个参数_10年架构师深解java核心技术:方法参数+对象构造,确定不学?...
方法参数 首先回顾一下在程序设计语言中有关参数传递给方法(或函数)的一些专业术语.值调用(call by value)表示方法接收的是调用者提供的值.而引用调用(call by reference)表 ...
- C++内存分配与对象构造的分离
在C++中,我们基本用new(delete)操作符分配(释放)内存.new操作符为特定类型分配内存,并在新分配的内存中构造该类型的一个对象.new表达式自动运行合适的构造函数来初始化每个动态分配的类类 ...
- Delphi 对象的创建(create)与释放(free/destory)
Delphi 对象的创建(create)与释放(free/destory) 1.Create参数为:nil/self/application的区别,最好能看到实际效果的区别 例如: My := TMy ...
最新文章
- R语言sample函数数据对象采样实战
- 批量修改文件夹下图片名称(Python)
- 接口隔离原则(ISP)
- merkle tree(hash tree)
- oracle 索引 lob 迁移,Oracle 11g到19c迁移TB级lob表的酸爽
- 用js来实现那些数据结构01(数组篇01-数组的增删)
- 数据结构丿丶树 哈夫曼树
- 发光二极管压降, 也就是最小导通电压
- 新的 systemctl 命令代替原来的 chkconfig、service 命令
- Ceph Peering以及数据均衡的改进思路
- 18650锂电池知识全解析
- asset计算机语言,资产管理软件的各种语言翻译
- PostgreSQL恢复误删数据
- linux安装pycharm报错:Unable to detect graphics environment
- 北师大c语言2019在线作业,2019最新C语言考试题库及答案
- MBA案例分析: 美国西南航空的十年发展战略规划
- How to fix the global rice crisis 如何应对全球稻米危机 | 经济学人20230401版双语精翻
- 什么是绝对、相对定位
- 苏州各园林的地址和票价
- 《结构性思维》读书笔记