今天使用Delphi2007,一个误输入,无意中发现Delphi2007的record类型居然能够和TObject一样定义方法和属性,而且不需要调用类似TObject.Create方法就能生成一个record对象。这是否意味着Delphi2007也能和C++一样,不仅能使用堆对象(new),也能使用栈对象(静态对象)呢?

通过实验,答案是肯定的!这使我感到很兴奋,因为Delphi从诞生之日起,就限定了只能继承于TObject的堆对象,必须通过Create和Free来建立和销毁一个对象,而不能使用栈对象。而栈对象的好处就在于它能和其它类型一样很方便的定义,它能自动调用构造函数和析构函数,在作用域范围内(如函数内的局部对象)不必当心对象的建立和销毁问题。要是Delphi具有了该功能,无意是Delphi编程者们的福音。

不过,进一步的测试却比较失望,请看下面的代码:

type
TMyRecord = record
private
x: Integer;
y: Integer;
public
// error: Parameterless constructors not allowed record types
// constructor Create;
// error: A record cannot introduce a destructor
// destructor TMyRecird;
constructor Create(a: Integer);
constructor TMyRecord; overload;
constructor TMyRecord(a, b: Integer); overload;
// constructor TMyRecord(a, b: Integer);
procedure Display;
property xi: Integer read x;
end; { TMyRecord } constructor TMyRecord.Create(a: Integer);
begin
x := a;
y := ;
end; procedure TMyRecord.Display;
begin
ShowMessage(Format('x = %d, y = %d', [x, y]));
end; constructor TMyRecord.TMyRecord;
begin
x := ;
y := ;
end; constructor TMyRecord.TMyRecord(a, b: Integer);
begin
x := a;
y := b;
end; procedure TForm1.Button1Click(Sender: TObject);
var
rec: TMyRecord;
begin
rec.TMyRecord(, );
rec.Display;
end;
可以看出,确实可以和C++一样定义一个局部record对象(不需要动态建立),而且可以使用该对象的方法和属性,请看TForm1.Button1Click方法的汇编码(CPU调试窗口粘贴下来的):
Unit1.pas.: begin
0045ACDC 83C4F8 add esp,-$
Unit1.pas.: rec.TMyRecord(, );
0045ACDF 8BC4 mov eax,esp
0045ACE1 B9C8000000 mov ecx,$000000c8
0045ACE6 BA64000000 mov edx,$
0045ACEB E8E4FFFFFF call TMyRecord.TMyRecord
Unit1.pas.: rec.Display;
0045ACF0 8BC4 mov eax,esp
0045ACF2 E855FFFFFF call TMyRecord.Display
Unit1.pas.: end;
0045ACF7 pop ecx
0045ACF8 5A pop edx
0045ACF9 C3 ret

从汇编码中看,定义的TMyRecord变量rec确实是标准C++栈对象一样的,在调用其方法的时候也隐含传递了Self指针(mov  eax,esp),也就是说,rec在这里已经区别于普通的record变量,而是一个实实在在的“对象”变量!

但是遗憾的是,它不能定义destructor方法,虽然可以定义constructor方法(不能定义为Tobject缺省的Create方法,带参数可以),但却不能在定义的时候自动调用构造方法(我原本以为和C++一样,定义一个和TMyRecord同名的constructor方法,可以自动调用的),如此一来,静态栈对象的主要优点就丧失了,如果手工调用构造方法,和定义一个普通record变量,然后调用静态过程没什么两样了。其实,Delphi已经把record改道这一步了,稍稍进一步就可以完完全全的使用栈对象,从技术上讲一点难度都没有,编译器只需要在栈中分配对象变量内存和销毁对象变量内存的同时,隐含调用一下构造方法和析构方法就可以了的。

虽然很遗憾,但是还是为Delphi的这点进步而高兴,至少我们可以利用这一功能封装record,而且使用这有限的栈对象可以不用当心对象本身的销毁问题(record对象中动态分配的内存还是得手工释放或者调用它的某个方法释放)。

后记:以前在DOS下,以C/C++为主,Pascal只用过Turbo Pascal4.0,对以后Pascal的版本并不十分了解,今天看了网友housisong的留言,才知道我所谓的新功能--有限栈对象,Delphi中早就有了,如Delphi7.0就可以使用Object关键字定义栈对象,而且比2007的record类型还完善一些,record不能继承,而object对象能够继承,看来我真是孤陋寡闻了!!!

Delphi2007新功能 -- 有限的栈对象的更多相关文章

  1. C++——内存对象 禁止产生堆对象 禁止产生栈对象

    用C或C++写程序,需要更多地关注内存,这不仅仅是因为内存的分配是否合理直接影响着程序的效率和性能,更为主要的是,当我们操作内存的时候一不小心就会出现问题,而且很多时候,这些问题都是不易发觉的,比如内 ...

  2. Spring总结 4.AOP之为对象添加新功能

    Spring除了提供增强原有功能的方法外,还提供了为一个对象引入新功能的方法.如下: package cn.powerfully.service; public interface IService ...

  3. Spring实战(十)Spring AOP应用——为方法引入新功能、为对象引入新方法

    切面最基本的元素是通知和切点,切点用于准确定位应该在什么地方应用切面的通知. 1.Spring借助AspectJ的切点表达式语言来定义Spring切面 在Spring中,要使用AspectJ的切点表达 ...

  4. PHP5各个版本的新功能和新特性总结

    因为 PHP 那“集百家之长”的蛋疼语法,加上社区氛围不好,很多人对新版本,新特征并无兴趣.本文将会介绍自 PHP5.2 起,直至 PHP5.6 中增加的新特征 本文目录:PHP5.2 以前:auto ...

  5. CentOS以及Oracle数据库发展历史及各版本新功能介绍, 便于构造环境时有个对应关系

    CentOS版本历史 版本 CentOS版本号有两个部分,一个主要版本和一个次要版本,主要和次要版本号分别对应于RHEL的主要版本与更新包,CentOS采取从RHEL的源代码包来构建.例如CentOS ...

  6. PHP5各个版本的新功能和新特性总结(转载 http://www.jb51.net/article/48150.htm)

    本文目录:PHP5.2 以前:autoload, PDO 和 MySQLi, 类型约束PHP5.2:JSON 支持PHP5.3:弃用的功能,匿名函数,新增魔术方法,命名空间,后期静态绑定,Heredo ...

  7. VS2015预览版中的C#6.0 新功能(二)

    VS2015预览版中的C#6.0 新功能(一) VS2015预览版中的C#6.0 新功能(三) 自动属性的增强 只读自动属性 以前自动属性必须同时提供setter和getter方法,因而只读属性只能通 ...

  8. [译] OpenStack Pike 版本中的 53 个新功能盘点

      原文:https://www.mirantis.com/blog/53-things-to-look-for-in-openstack-pike/ 作者:Mirantis Nick Chase 发 ...

  9. OpenStack Q版本新功能以及各核心组件功能对比

    OpenStack Q版本已经发布了一段时间了.今天, 小编来总结一下OpenStack Q版本核心组件的各项主要新功能, 再来汇总一下最近2年来OpenStack N.O.P.Q各版本核心组件的主要 ...

随机推荐

  1. Mac上利用Aria2加速百度网盘下载

    百度网盘下载东西的速度那叫一个慢,特别是大文件,看着所需时间几个小时以上,让人很不舒服,本文记录自己在mac上利用工具Aria2加速的教程,windows下思路也是一样! 科普(可以不看) 这里顺带科 ...

  2. 第四次JAVA作业

    public class TvbDog { public static void main(String[] args) {  Dog per=new Dog("陈狗"," ...

  3. 安全警告——“Windows已经阻止此软件因为无法验证发行者”解决办法

    步骤:打开IE工具-->Internet选项-->安全-->自定义级别 -->找到ActiveX 控件和插件,按照图里进行配置.

  4. [CF632A]Grandma Laura and Apples

    题目大意:有$n$个顾客买苹果,每个买一半的苹果,有时会送半个苹果.最后卖光了,问卖了多少钱 题解:倒退过来,可以把半个苹果当做一份来算,这样不会有小数 卡点:无 C++ Code: #include ...

  5. linux 条件判断式

    1.利用if ...then if [ 判断条件 ];then 指令 fi 实例一 Y/N: #!/bin/bash #Program: # This program shows "Hell ...

  6. [hdu 3949]线性基+高斯消元

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3949 一开始给做出来的线性基wa了很久,最后加了一步高斯消元就过了. 之所以可以这样做,证明如下. 首 ...

  7. [hdu 2298] 物理推导+二分答案

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2298 #include<bits/stdc++.h> using namespace st ...

  8. mysql__视图

    视图 1.什么是视图 视图是一种虚拟存在的表,对于使用视图的用户来说基本上是透明的.视图并不是在数据库中实际存在的,行和列数据来自定义视图的查询中使用的表,并且是在使用视图时动态生成的 视图相对于普通 ...

  9. VC关于置顶窗口的方法小结

    转摘自:http://blog.csdn.net/wirror800/article/details/4002381 将窗体置顶的方法有: //将窗体置顶的API函数 ::SetWindowPos(m ...

  10. HDU1232 畅通工程---(经典并查集应用)

    http://acm.hdu.edu.cn/showproblem.php?pid=1232 畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory ...