不是什么时候都可以用栈来声明对象并使用(自动释放)——Delphi里到处都是编译器魔法,并且自动帮助实例化界面元素指针
一直都喜欢这样显示窗口,因为简单高效:
void MainWidget::ShowMyWindow()
{
MyWidget form(this);
form.resize(,);
form.exec();
}
今天忽然想到一个问题,栈的空间只有1M或者2M,一个窗口如果数据比较多的话,就装不下,这时候就不能使用栈来声明、使用和销毁对象了。所以就要这样写:
void MainWidget::ShowMyWindow()
{
MyWidget* form;
form = new MyWidget(this);
form->resize(,);
form->exec();
delete form;
}
因为好奇,所以动手实测了一下:
void MainWidget::ShowMyWindow()
{
Util::ShowMessage(sizeof(MyWidget));
}
这个窗口也就112字节,离1024还比较远。但那也是因为所有界面元素都是动态生成的,所有界面元素在.h文件里全部都是指针声明。否则的话,那也是不行的。
后来又测试了主窗口MainWidget,也就160,看来是够用了。
但是我特别注意到,像QSharedMemory这样真正用来记录数据的东西,不应该在栈上建立实例,否则很可能会堆栈溢出。
------------------------------------------------------------------------
题外话,Delphi窗体里虽然有众多的界面元素,但通过编译器魔法,其实也都是指针而已。当TForm.Create(self)的时候,实际上VCL帮你把所有界面元素从dfm文件中读出数据,然后自动初始化(生成实例)了:
procedure TForm1.Button1Click(Sender: TObject);
begin
FrmFinance:=TFrmFinance.Create(self);
with FrmFinance do
try
InitForm(strNumero);
ShowModal;
finally
Free;
end;
end;
这么重要的思想到今天才认识到,感觉有点失败。。。Delphi程序员们真是温室里的花朵(我是其中一朵),生在福中而不至福啊!!
为了证实这一点,现在做个小实验,新建一个项目,上面只放一个按钮Button1,然后输入以下代码:
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(IntToStr(sizeof(TForm1)));
ShowMessage(IntToStr(sizeof(TButton)));
ShowMessage(IntToStr(sizeof(self)));
end;
结果这三个值都是4,这其实是三个指针的长度值,真是活生生领略了Delphi的“编译器魔法”,C++就不这样,sizeof可以直接评估类所占用的内存大小。
不过没关系,Delphi也有自己的过墙梯:
procedure TForm1.Button1Click(Sender: TObject);
var
myform : TForm;
begin
myform := TForm.Create(self);
ShowMessage(IntToStr(myform.InstanceSize)); //
ShowMessage(IntToStr(button1.InstanceSize)); //
ShowMessage(IntToStr(self.InstanceSize)); //
end;
结果发现,三个值分别是760、536和764。这里特别注意第三个值,是myform的内存长度(760)+Button1指针的内存长度(4),而不是myform(760)+Button1实例的长度(536)。如果再增加一个TMemo,那么form1的长度就差成了760+2*4=768,实测无误。
既然如此,请问这个Button1是什么时候实例化对象的呢?答案就是读取dfm的时候,具体哪一句语句?我估计是这句:
implementation
{$R *.dfm}
其实这还不是一句编程的语句,所以什么内容都看不到,只能等有时间研究Lazarus的实现代码了。
不是什么时候都可以用栈来声明对象并使用(自动释放)——Delphi里到处都是编译器魔法,并且自动帮助实例化界面元素指针的更多相关文章
- [原创]java WEB学习笔记59:Struts2学习之路---OGNL,值栈,读取对象栈中的对象的属性,读取 Context Map 里的对象的属性,调用字段和方法,数组,list,map
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- .NET的堆和栈03,引用类型对象拷贝以及内存分配
在" .NET的堆和栈01,基本概念.值类型内存分配"中,了解了"堆"和"栈"的基本概念,以及值类型的内存分配.我们知道:当执行一个方法的时 ...
- Qt浅谈之一:内存泄露(总结),对于QWidget可以setAttribute(Qt::WA_DeleteOnClose),而且绝对不能手动删除栈上的对象
一.简介 Qt内存管理机制:Qt 在内部能够维护对象的层次结构.对于可视元素,这种层次结构就是子组件与父组件的关系:对于非可视元素,则是一个对象与另一个对象的从属关系.在 Qt 中,在 Qt 中,删除 ...
- Delphi内存管理(Integer、Boolean、Record、枚举等都是在作用域内编译器自动申请内存,出了作用域自动释放;另外,字符串、Variant、动态数组、接口也是由Delphi自动管理)
一.什么是堆.栈? 程序需要的内存空间分为 heap(堆) 和 stack(栈),heap 是自由存储区, stack 是自动存储区,使用 heap 需要手动申请.手动释放, stack 是自动申请. ...
- Eclipse中自动提示的方法参数都是arg0,arg1的解决方法
Eclipse中自动提示的方法参数都是arg0,arg1,就不能根据参数名来推断参数的含义,非常不方便. 解决方法:Preferences->Java->Installed JREs,发现 ...
- 到处都是坑的微信支付V3之 微信支付回调页面
据上次 到处都是坑的微信支付V3 后很多园友在被虐了千百遍后终于跳转到了亲切的微信支付界面,但输入密码支付后却不知道怎么处理了,接下来补上支付后的处理流程. 1. html中根据前台支付后反馈信息成功 ...
- 到处都是坑的微信支付V3
业务需要一个在微信上能付款的功能,于是乎想到了最普遍的支付宝,坑爹的是T与A是水火不容啊,默默的还是接微信支付吧,没想到从此掉进了连环坑…… 网上写微信支付接口的还是很多,PHP官方有(鄙视源码作者, ...
- 《剑指Offer》第1题(Java实现):在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
一.题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该 ...
- Hadoop概念学习系列之谈hadoop/spark里为什么都有,YARN呢?(四十一)
在Hadoop集群里,有三种模式: 1.本地模式 2.伪分布模式 3.全分布模式 在Spark集群里,有四种模式: 1.local单机模式 结果xshell可见: ./bin/spark-submit ...
随机推荐
- Hadoop2.6 Ha 安装
Hadoop 2.6安装文档 版本说明:hadoop 2.6 linux-64位 Zookeeper3.4.6 jdk 1.7.0_75 1. Ssh无密码 ssh-keygen vim ...
- sorl6.0+jetty+mysql
sorl6.0+jetty+mysql搭建solr服务 1.下载solr 官网:http://lucene.apache.org/solr/ v2.目录结构如下 v3.启动solr(默认使用jetty ...
- PDF417码
PDF417码是由留美华人王寅敬(音)博士发明的.PDF是取英文Portable Data File三个单词的首字母的缩写,意为“便携数据文件”.因为组成条码的每一符号字符都是由4个条和4个空构成,如 ...
- Qt浅译:JSON Support in Qt(JSON只有六种数据类型)
JSON Support in Qt Qt5之后开始提供对处理JSON数据的支持,JSON是一种Interter数据交换的数据格式. JSON 用于存储结构化的数据,JSON有6种基本数据类型 ...
- [WPF疑难]Hide me! not close
原文 [WPF疑难]Hide me! not close [WPF疑难]Hide me! not close 周银辉 有朋友遇到这样的一个问 ...
- Uva 10935 Throwing cards away I
题目意思:有N张牌,标号为1~N,且牌以叠好,从上到小就是标号1-N的牌,只要牌堆数量大于等于2的时候,就采取如下操作:将最上面的牌扔掉(即离开牌堆).刚才那张牌离开后,再将新的最上面的牌放置于牌堆最 ...
- [置顶] android网络通讯之HttpClient4不指定参数名发送Post
在HttpClient4之前都是通过List<NameValuePair>键值对的形式来向服务器传递参数 ,在4.0版本中在加入了不指定参数名发送数据的形式,利用StringEntity来 ...
- java学习——入门扫盲篇
概要 近期这几天開始进入java的学习,接触到了好多不是非常了解的概念,像JDK.JRE.JVM.GC等等这些,放到这里来进行下扫盲. java java是一种面向对象程序设计语言和java平台的总称 ...
- 已经上架的app(可供销售)在AppStore上搜不到的解决办法
这两天很是头大, 因为3天前手动发布的app到现在都还没在AppStore上看到,打了无数电话给苹果和发邮件给review团队. 下面说说怎么解决我们在iTunes后台看到是绿灯(可供销售)但是就是在 ...
- UITabbar的常用属性
// //设置tabbar的背景颜色 // [self.tabBar setBarTintColor:[UIColor redColor]]; // //设置选中时图片和文字的颜色 // [self. ...