================Delphi对象所占内存空间大小============================== 对象所占的内存空间大小取决于这个对象中的数据成员,加上一个4字节的VMT,成员函数不占空间。 注意:编译器对于无法合并的小于32位空间的数据域填充到32位大小,以加快存取速度。所以两个16位的word会被合并成一个integer。但一个单独16位的word会被扩展成一个integer
procedure TForm1.Button1Click(Sender: TObject); var Obj : TMyClass; begin Obj := TMyClass.Create(); with memo1.Lines do begin Add('对象大小:' + IntToStr(Obj.InstanceSize)); Add('对象所在地址 :' + IntToStr(Integer(Obj))); Add('FMember1所在地址:' + IntToStr(Integer(@Obj.FMember1))); Add('FMember2所在地址:' + IntToStr(Integer(@Obj.FMember2))); Add('FMember3所在地址:' + IntToStr(Integer(@Obj.FMember3))); Add('FMember4所在地址:' + IntToStr(Integer(@Obj.FMember4))); end; Obj.Free(); end;
======================类方法和类引用================================
1. 定义类方法(静态方法),它无法操作对象的数据成员,加上class关键字: class function TObject.ClassName: ShortString; 构造函数 create其实就是一个类方法。
2. 定义类引用(元类,更抽象): TMyClass = class; TMyClassClass = class of TMyClass; // TMyClassClass就是类引用
用法: TMyClass = class; public class procedure Show(); // 类方法 end; TMyClassClass = class of TMyClass; var MyClass : TMyClassClass; MyObj: TMyClass; begin MyObj := MyClass.Create();// 注意:引用类MyClass直接调用了类方法。其作用与MyObj := TMyClass.Create(); 完全相同 MyClass.Show(); MyObj.Free(); end;
主要用作类型参数化上,因为有时候在编译时无法得知某个对象的具体类型,而要调用其类方法(如构造函数),此时可以将类型作为一个参数来传递。 比如:Application.CreateForm(TForm1, Form1);
procedure TApplication.CreateForm( // TComponentClass = class of TComponent; 类引用类型 InstanceClass: TComponentClass; var Reference ); 允许在运行期确定类型,可以给程序带来莫大的灵活性。
3. Self代表类,因此可以调用类方法,但不能访问对象数据成员 class function ClassMethod1(): integer; 调用的时候可以 self.ClassMethod1();
====================面向对象的错误用法==================================
1. 定义一堆系统函数在一个类里。 其实它什么都没有封装,只是一堆函数的集合而已,是一个没有状态(数据成员)的类。 它不是活的,它所生成的每个对象之间没有任何差别。 2. 如果只有Get/Set函数的类,还是称不上类。 虽然状态是活的,但实际上什么没有隐藏任何东西,也没有简化任何东西。这样的类与record没有任何区别。
什么是设计优良的类? 一个文件操作类:具有状态信息,接口简单、明了、易用。它封装了所有对文件操作的算法,客户端程序不必限于复杂的文件操作的代码中。
|
请发表评论