Delphi - 对象构造浅析后续
技術交流,DH講解.
之前一篇文章已經講過對象構造的過程,但是我們那個對象無任何東西,這里我們在已有的基礎上面加點兒東西再來看看.
代碼改成:
我們可以看到多了一個私有域和公有方法.
構造過程:
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
?
最后來做個試驗,我們給類里面再加一個私有成員,然后實現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 - 对象构造浅析后续的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 开机u盘启动怎么设置 如何设置开机启动U
- 下一篇: 战神z6怎么改win7 战神z6升级wi