delphi self 的使用
delphi之self
在使用delphi的对象技术的时候,经常会看到一个词汇:self,它到底指的是什么呢?
我们还要从对象与类的关系谈起。 类是对将要创建的对象的性质的描述,是一种文档。这很重要:
类只是一段描述性的文字,它并不会真去分配内存,无论在其中定义多少变量。 如果打个比方,
类就是图纸,而对象就是根据图纸盖的房子。对象是真正在 内存中存在的东西,是运行“实体”。
根据一份图纸可以盖多个相似的房子,同 样道理,根据一个类,可以创建多个类似的对象,
这个过程叫做“实例化”。在delphi中使用对象技术,要遵循以下的步骤:
1。定义一个类
2。用该类声明一个名字(实质是一个指针)
3。用该类实例化一个对象,并使它与先前的名字联系起来
4。调用对象的方法或属性
5。释放对象
下面我们写一个最简单的表达累加器功能的类
type
TCount = class
private
FNum: integer; // 记录有多少个数字被累加
FSum: integer; // 当前的累加和
pubic
procedure Add(n: integer) // 把整数n累加进去
procedure clear; // 清零
procedure show; // 显示当前信息
constructor create; // 构造函数
end;
....
使用的过程是这样的:
var a: TCount; // 这里只是声明了一个名字,并非真正地分配了一个对象
...... // a这个变量只占用4字节地内存
a := TCount.create; // 在堆空间中分配内存,并把首地址拷贝到a中。
a.add(5);
a.add(7);
a.show(); // 以上是调用a对象的有关方法
a.free; // free会去调用析构函数,完成堆空间的释放。
我们看这样一个问题:一个对象到底占用多大的内存空间?
答案是很小!因为在分配一个对象地时候,实际上只分配了类中定义的数据,
而没有分配其中的函数所需要的空间。这些类中定义的函数(称为成员函数),
与普通函数一样被存放在静态地址空间中。
这样就引出了第二个问题:既然对象的数据和操作这些数据的方法不是存在一起,
那么这些函数如何才能知道到底要操作哪个数据块呢?(类可生成多个实例)
显然,最容易想到的解决办法就是让这些特殊函数带一个参数,是个指针类型,
该指针指示要操作的数据块的首地址。
事实上,成员函数正是这样做的,它们有一个缺省的参数self,这是个指针类型,
对于上边的例子,它的定义就是:TCount self。编译器在遇到调用a.add(5)的时候,
把它解释为:TCount.add(a,5);把代表对象的数据块的地址送给add函数作为第一个参数--隐含的参数。
说得本质一些就是:self是当前正在执行本函数的那个对象的数据块的首地址。
self既然代表对象自己,那么难道自己还用定义吗?看下边的代码:
procedure TForm1.button1click(sender: TObject);
var
a: TButton;
begin
a := Tbutton.create(self);
....
end;
在创建Tbutton类的对象的时候,需要给出一个内存管理者。
self就表示了正在运行button1click这个过程的那个对象(的数据块的首地址)。其实大多数情况下就是form1。//这里的理解有点问题应该是OWER管理者
Delphi之覆盖和隐藏
如果一个子类方法声明指定的标识符与继承得到的方法具有相同的名称,
但是未包含override,那么新的声明只是隐藏(hides)了父类方法。也就是说子类和父类方法同样存在,
父类方法是静态的,并未被覆盖,例如:
type
T1=class(TObject)
procedure Act;virtual;//virtual也好,或则dynamic也好,只是说明此方法可被覆盖
end;
T2=class(T1)
procedure Act;//Act再次被声明,但是因为没有被声明为overriden,所以没有覆盖父类T1的相应方法
end;
var
SomeObject:T1;
begin
SomeObject:T2.Create;
SomeObject.Act;//这里实际调用的是T1.Act
end;
关于Sender,Self,Owner和parent
Sender--意义:指本对象。
Sender在什么对象相关代码里,那么Sender就是什么。
Self--意义:指本类,也就是Self被引用的类。比如若在类TMyClass内引用了Self,
那么Self=TMyClass.
Owner--意义:哪个对象释放我的内存啊?
如:Pan:=TPanel.Create(Self);其中Create的参数是:AOwner:TComponent。
Owner释放Pan的内存。因为窗口释放Pan的内存,
但窗口类的对象是Self.一般给Owner传Self就可以。
比如:
代码段一:
pan:=TPanel.Create(Self);
with Pan do begin
try
Left:=20;
Top:=20;
parent:=Self; //Parent:=Form1也可以。
Visible:=true;
ShowMessage('Created');
finally
Pan.free;
end;
end;
-----------------------------------------------------
Parent--
意义:此对象包括在哪个对象里那?
说明:若组件不是从TControl继承来的,那么在创建组件后不必声明此属性。
delphi self 的使用的更多相关文章
- 学习笔记:7z在delphi的应用
最近做个发邮件的功能,需要将日志文件通过邮件发送回来用于分析,但是日志文件可能会超级大,测算下来一天可能会有800M的大小.所以压缩是不可避免了,delphi中的默认压缩算法整了半天不太好使,就看了看 ...
- delphi连接sql存储过程
针对返回结果为参数的 一. 先建立自己的存储过程 ALTER PROCEDURE [dbo].[REName] ) AS BEGIN select ROW_NUMBER() over(order by ...
- delphi 2010与delphi XE破解版的冲突
在系统中同时安装了Dephi 2010LITE版与Delphi XE lite后,总是会有一个有问题 是因为两者都是读取C:\ProgramData\Embarcadero目录下的license文件, ...
- [Delphi] Delphi版本号对照
VER300 Delphi Seattle / C++Builder Seattle 23 230 (Delphi:Win32/Win64/OSX/iOS32/iOS64/An ...
- delphi tidhttp 超时设置无效的解决方法
现在delphi都发布到xe8了,tidhttp还有缺陷,那就是超时设置在没有网络或者连不上服务器的时候是无效的,不管你设置为多少都要10-20秒.connectTimeout和readTimeout ...
- Delphi Code Editor 之 编辑器选项
Delphi Code Editor 之 编辑器选项 可从Code Editor的右键菜单中选择“Properties”菜单项来查看编辑器选项.也可以从主菜单[Tools | Editor Optio ...
- Delphi使用ADO进行数据库编程
Delphi是一个可视化的编程工具,ADO编程也是这样,所以话不多言,直接通过代码.截图和语言来说明. 我的数据库是Oracle,为了测试,先建一个表:create table practice(un ...
- 怎么使用Delphi获取当前的时间,精确到毫秒
先介绍一个可能比较常用的方法,获取当前时间 var datetime: string; begin datetime:= FormatDateTime('yyyy-mm-dd hh:mm:ss', N ...
- Delphi在创建和使用DLL的时候如果使用到string,请引入ShareMem单元
当使用了长字符串类型的参数.变量时,如string,要引用ShareMem. 虽然Delphi中的string功能很强大,但若是您编写的Dll文件要供其它编程语言调用时,最好使用PChar类型.如果您 ...
- Delphi控件之---通过编码学习TStringGrid(也会涉及到Panel控件,还有对Object Inspector的控件Events的介绍
我是参考了万一的博客里面的关于TStringGrid学习的教程,但是我也结合自己的实际操作和理解,加入了一些个人的补充,至少对我有用! 学用TStringGrid之——ColCount.RowCoun ...
随机推荐
- Python之路(五)-->> 格式化
在Python中格式化的方式有两种,一种是%,另外一种是format()格式化. ----------------------------------------------------------- ...
- 20155202 《Java程序设计》实验二(面向对象程序设计)实验报告
20155202 <Java程序设计>实验二(面向对象程序设计)实验报告 代码托管 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉 ...
- 2017-2018-1 20155307 《信息安全系统设计基础》第十周课上未完成补充以及课下IPC作业
课上内容2:stat命令的实现-mysate 学习使用stat(1),并用C语言实现 提交学习stat(1)的截图 man -k ,grep -r的使用 伪代码 产品代码 mystate.c,提交码云 ...
- How to bind a Command on a ContextMenu within a DataTemplate using MVVM
Since the Popuup control has it's separate visual tree, you cannot use find ancestor to find the Gri ...
- #ifdef 支持Mac #ifndef 支持Windows #if defined (Q_OS_WIN) 应该可以再两个系统通用
//mac qt可以运行 #ifdef Q_OS_MAC qDebug()<<QSysInfo::MacintoshVersion; #endif //Mac不运行 #ifndef Q_O ...
- 【转载】C/C++杂记:虚函数的实现的基本原理
原文:C/C++杂记:虚函数的实现的基本原理 1. 概述 简单地说,每一个含有虚函数(无论是其本身的,还是继承而来的)的类都至少有一个与之对应的虚函数表,其中存放着该类所有的虚函数对应的函数指针.例: ...
- GDAL中通过GDALDriver类的Create函数实现图像的保存
GDAL中除了读取各种类型的图像外,也可以实现对各种图像的保存操作,具体实现测试代码如下: int test_gadl_GDALDataset_write() { const char* image_ ...
- CF833E Caramel Clouds
题面 天上有$n$朵云,每朵云$i$会在时间$[l_i,r_i]$出现,你有$\text C$个糖果,你可以花费$c_i$个糖果让云$i$消失,同时需要保证你最多让两朵云消失.现在有$m$个独立的询问 ...
- 【mysql经典题目】科目成绩都大于80分\每个科目的第一名\总成绩排名
参考:http://blog.csdn.net/lifushan123/article/details/44948135 1.查询出科目成绩都大于80分的学生的名字? drop table if EX ...
- HttpRunner安装笔记(1)安装环境准备:pyenv安装
HttpRunner建议在Python 3.4 及以上版本,但是centos有其他功能模块基于python2.7,所以使用pyenv安装多版本pyhon版本. pyenv 是一款特别好用的Python ...