delphi高手突破学习笔记之面向对象类和对象的本质(有汇编解释 good)
知识点1:堆和栈
每个应用程序可以获得的内存空间分为两种:堆(heap)和栈(stack)。
堆又称为“自由存储区”,其中的内存空间的分配与释放是必须由程序员来控制的。例如,用GetMem函数获取了一定大小的内存空间,则在使用完后,必须调用FreeMem函数将空间释放,否则就会发生所谓的“内存泄漏”。“借债还钱,天经地义”。
栈又称为“自动存储区”,其中的内存空间的分配与释放是由编译器和系统自动完成的,不需要程序员过问。函数调用时按值传递的参数所占空间、函数中的局部变量等,都是在栈中被分配空间的。比如函数:
- var
- i : Integer;
- j : Integer;
- begin
- for i := 1 to 10 do
- ......
- ......
- end;
其中,i和j的空间是由编译器在栈中分配的。在函数末尾,也不需要程序员手动去释放这两个变量所占的内存空间。
Objecgt Pascal遵循所谓的“引用/值”模型。无论在参数传递还是变量定义中,简单类型(如Integer、Cardinal、char以及record等)被按值传递或使用,其内存空间从栈中分配。
而复杂类型(class)则被按引用传递或使用,其内存空间从堆中分配。在Object Pascal中,所有对象(类类型的)都被建立在内存的堆空间上,而非栈上。因此在创建对象时,其构造函数不会被编译器自动调用,也没有C++中所谓的“默认构造函数”。调用构造函数来创建对象以及调用析构函数来消灭对象都是程序员的职责。
知识点2:构造函数与对象内存的分配
定义构造函数使用Constructor关键字。按惯例,构造函数名称为Create(当然也可以用其他名称,但那绝非优良的设计)。要创建出一个对象,首先需要分配对象本身所占用的内存空间,然后执行类的构造函数,以初始化各数据成员、申请对象需要的资源或创建其内部包含的子对象。编译器在执行类似MyFamilyObject := TMyFamily.Create(‘Zhang’, ‘Li’);这样的构造函数之前,会插入以下几行汇编代码:
- test dl, dl
- jz +$08
- add esp, -$10
- call @ClassCreate // 注意这行代码
以上代码的最后一行代码调用的是system.pas文件的第8949行的_ClassCreate函数。内存分配完成后是调用类的构造函数,即TMyClass.Create(),以初始化数据成员。构造函数由定义类的程序员编写,也就是说,将对象初始化成何种模样是由程序员决定的。至此,一个对象已经诞生了。之后,编译器会再插入以下几行汇编代码:
- test dl, dl
- jz +$0f
- call @AfterConstruction
- pop dword ptr fs:[$00000000]
- add esp, $0c
构造函数的职责只是初始化对象的数据成员,没有构造函数只意味着不会对数据成员进行初始化而已,编译器会对所有数据进行清零初始化。
知识点3:析构函数与对象内存的回收
定义析构函数使用Destructor关键字。按惯例,析构函数名称为Destroy。
- type
- TMyClass = class
- Public
- Destructor Destroy(); override;
- End;
在析构对象的时候,应该调用对象的Free()方法而不是直接调用Destroy()。
这是因为,在TObject的Free()方法中会判断对象本身是否为nil,如果不为nil则调用对象的Destroy(),以增加安全性。既然有这样更安全的做法,当然没有理由不这么做了。
永远不要直接调用对象的Destroy(),而应该是Free()。
知识点4:实例介绍
- unit DllLoader;
- interface
- uses windows;
- Type
- TDllLoader = class
- Protected
- // 之所以是protected成员,是为了在其派生类中具体实现加载某DLL时,派生类 能够访问该句柄
- FhDLL : HMODULE;
- Public
- Constructor Create(strDLLName : String);
- Destroctor Destroy(); override;
- End;
- Implementation
- Constructor TDllLoader.Create(strDLLName : String);
- Begin
- FhDLL := LoadLibrary(strDLLName); // 构造函数中加载DLL
- ASSERT(FhDLL <> 0);
- End;
- Destructor TDllLoader.Destroy();
- Begin
- If FhDLL <> 0 then
- begin
- FreeLibrary(FhDLL); // 析构函数中释放DLL
- FhDLL := 0;
- End;
- End;
- End.
知识点5:“类方法”与“类引用”类型
一般所称的“方法”,都是指“对象方法”。也就是说,执行该方法,将可能导致对象的状态发生改变,即该方法可以更改对象的数据成员的值。如:
- TMyClass2 = class
- private
- FMember : Integer;
- pubic
- procedure SetValue(Value : Integer);
- end;
- procedure TMyClass2.SetValue(Value : Integer);
- begin
- FMember := Value;
- end;
其中SetValue即为典型的对象方法。
除了“对象方法”外,还有所谓的“类方法”,也就是属于类级别的函数(而非对象级别的)。它可以改变类的状态(而非对象的状态)。
定义类方法,只需要在一般的方法声明前加上class关键字。如:
- class function TObject.ClassName: ShortString;
既然类方法是进行类级别的操作,因此在类方法中是无法对对象的数据成员进行访问的。以下的代码展示了类方法中self的使用方法:
- interface
- Type
- TClassMethodExample = class
- private
- FnInteger : Integer;
- public
- class function ClassMethod1() : Integer;
- class function ClassMethod2() : Integer;
- function Method() : Integer;
- end;
- implementation
- { TClassMethodExample }
- class function TClassMethodExample.ClassMethod1: Integer;
- begin
- self.Method() ; // 非法,因为Method不是类方法
- self.ClassMethod2(); // 合法
- end;
- class function TClassMethodExample.ClassMethod2: Integer;
- begin
- Result := self.nInteger; // 非法,类方法中不能访问对象数据成员
- end;
- function TClassMethodExample.Method: Integer;
- begin
- Result := 0;
- end;
- end.
http://blog.csdn.net/sushengmiyan/article/details/7506310
delphi高手突破学习笔记之面向对象类和对象的本质(有汇编解释 good)的更多相关文章
- delphi高手突破学习笔记之面向对象类和对象的本质
知识点1:堆和栈 每个应用程序可以获得的内存空间分为两种:堆(heap)和栈(stack). 堆又称为“自由存储区”,其中的内存空间的分配与释放是必须由程序员来控制的.例如,用GetMem函数获取了一 ...
- python cookbook第三版学习笔记十:类和对象(一)
类和对象: 我们经常会对打印一个对象来得到对象的某些信息. class pair: def __init__(self,x,y): self.x=x self. ...
- [javase学习笔记]-6.2 类与对象的关系
这一节我们来看一下类与对象之间的关系. 我们学习java语言,目的就是用java语言对现实生活中的事物进行描写叙述.那么我们如何来描写叙述呢.这就引出了类,我们在实际实现时,是通过类的形式来体现的. ...
- delphi VCL研究之消息分发机制-delphi高手突破读书笔记
1.VCL 概貌 先看一下VCL类图的主要分支,如图4.1所示.在图中可以看到,TObject是VCL的祖先类,这也是Object Pascal语言所规定的.但实际上,TObject以及TObject ...
- java学习-初级入门-面向对象⑥-类与对象-静态static
这次我们来学习静态(static) 知识点 1.静态方法只能调用静态变量 2.静态变量属于整个Class,会随着发生变化. 案例:定义一个自动增长的学生类. 题目要求: 定义一个学生类,除了姓名.性别 ...
- python cookbook第三版学习笔记十三:类和对象(三)描述器
__get__以及__set__:假设T是一个类,t是他的实例,d是它的一个描述器属性.读取属性的时候T.d返回的是d.__get__(None,T),t.d返回的是d.__get__(t,T).说法 ...
- ES6学习笔记四(类和对象)
{ // 构造函数和实例 class Parent{ constructor(name='mukewan'){ this.name=name; } } let v_parent=new Parent( ...
- python cookbook第三版学习笔记十三:类和对象(四)描述器
__get__以及__set__:假设T是一个类,t是他的实例,d是它的一个描述器属性.读取属性的时候T.d返回的是d.__get__(None,T),t.d返回的是d.__get__(t,T).说法 ...
- python cookbook第三版学习笔记十一:类和对象(二)调用父类的方法
在子类中调用父类的方法,可以下面的A.spam(self)的方法. class A(object): def spam(self): print 'A.spam' class ...
随机推荐
- 深入浅出—JAVA(5)
5.编写程序
- Microsoft Jet 数据库引擎找不到对象'Sheet1$_'。请确定对象是否存在,并正确地写出它的名称和路径
We have a CRM add-on for Importing Price Lists into CRM. For this tool, we expect the details to be ...
- Week14(12月11日):路由
Part I:提问 =========================== 1.Visual Studio 2013自带ASP.NET MVC最高版本为(). A.3 B.4 C.5 D.6 2 ...
- MVC项目中如何判断用户是在用什么设备进行访问
使用UAParser在C#MVC项目中如何判断用户是在用什么设备进行访问(手机,平板还是普通的电脑) 现在我们开发的很多web应用都要支持手机等移动设备.为了让手机用户能有更加好的用户体验,我们经常为 ...
- hibernate 单元测试 5.2
单元测试 测试 dao service action package com.kaishengit.test; import org.hibernate.Session; import com.ka ...
- Mac OS X10.9安装的Python2.7升级Python3.3步骤详解
Mac OS X10.9默认带了Python2.7,不过现在Python3.3.3出来了,如果想使用最新版本,赶紧升级下吧.基本步骤如下 第1步:官网下载Python3.3 这里面有windows和m ...
- 告别IE给我们的web开发带来的困扰(使用chrome frame v8引擎)
茶爸爸个人微信:benyzhous,公众号:cha-baba欢迎骚扰 由于客户所有机器必须使用IE6浏览器,导致我们在开发项目过程中遇到非常多的样式与性能问题,在偶然的一次使用360软件管家搜索chr ...
- Web调试利器fiddler使用
fiddler官网:http://fiddler2.com/ http://wenku.baidu.com/view/053e79d776a20029bd642dc1 http://www.cnblo ...
- VBS脚本病毒特点及如何防范3(转)
5.Vbs病毒生产机的原理介绍 所谓病毒生产机就是指可以直接根据用户的选择产生病毒源代码的软件.在很多人看来这或许不可思议,其实对脚本病毒而言它的实现非常简单. 脚本语言是解释执行的.不需要编译,程序 ...
- 1245 - Harmonic Number (II)(规律题)
1245 - Harmonic Number (II) PDF (English) Statistics Forum Time Limit: 3 second(s) Memory Limit: 3 ...