一直都喜欢这样显示窗口,因为简单高效:

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里到处都是编译器魔法,并且自动帮助实例化界面元素指针的更多相关文章

  1. [原创]java WEB学习笔记59:Struts2学习之路---OGNL,值栈,读取对象栈中的对象的属性,读取 Context Map 里的对象的属性,调用字段和方法,数组,list,map

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  2. .NET的堆和栈03,引用类型对象拷贝以及内存分配

    在" .NET的堆和栈01,基本概念.值类型内存分配"中,了解了"堆"和"栈"的基本概念,以及值类型的内存分配.我们知道:当执行一个方法的时 ...

  3. Qt浅谈之一:内存泄露(总结),对于QWidget可以setAttribute(Qt::WA_DeleteOnClose),而且绝对不能手动删除栈上的对象

    一.简介 Qt内存管理机制:Qt 在内部能够维护对象的层次结构.对于可视元素,这种层次结构就是子组件与父组件的关系:对于非可视元素,则是一个对象与另一个对象的从属关系.在 Qt 中,在 Qt 中,删除 ...

  4. Delphi内存管理(Integer、Boolean、Record、枚举等都是在作用域内编译器自动申请内存,出了作用域自动释放;另外,字符串、Variant、动态数组、接口也是由Delphi自动管理)

    一.什么是堆.栈? 程序需要的内存空间分为 heap(堆) 和 stack(栈),heap 是自由存储区, stack 是自动存储区,使用 heap 需要手动申请.手动释放, stack 是自动申请. ...

  5. Eclipse中自动提示的方法参数都是arg0,arg1的解决方法

    Eclipse中自动提示的方法参数都是arg0,arg1,就不能根据参数名来推断参数的含义,非常不方便. 解决方法:Preferences->Java->Installed JREs,发现 ...

  6. 到处都是坑的微信支付V3之 微信支付回调页面

    据上次 到处都是坑的微信支付V3 后很多园友在被虐了千百遍后终于跳转到了亲切的微信支付界面,但输入密码支付后却不知道怎么处理了,接下来补上支付后的处理流程. 1. html中根据前台支付后反馈信息成功 ...

  7. 到处都是坑的微信支付V3

    业务需要一个在微信上能付款的功能,于是乎想到了最普遍的支付宝,坑爹的是T与A是水火不容啊,默默的还是接微信支付吧,没想到从此掉进了连环坑…… 网上写微信支付接口的还是很多,PHP官方有(鄙视源码作者, ...

  8. 《剑指Offer》第1题(Java实现):在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

    一.题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该 ...

  9. Hadoop概念学习系列之谈hadoop/spark里为什么都有,YARN呢?(四十一)

    在Hadoop集群里,有三种模式: 1.本地模式 2.伪分布模式 3.全分布模式 在Spark集群里,有四种模式: 1.local单机模式 结果xshell可见: ./bin/spark-submit ...

随机推荐

  1. awk参数详解

    wk是行处理器: 相比较屏幕处理的优点,在处理庞大文件时不会出现内存溢出或是处理缓慢的问题,通常用来格式化文本信息 awk处理过程: 依次对每一行进行处理,然后输出 awk命令形式: awk [-F| ...

  2. 关于Ubuntu12.04下code::blocks不能使用debug解决方法

    问题描述:   系统:ubuntu 12.04   code::blocks版本:10.05   问题现象:debug->start        之后出现:warning: GDB: Fail ...

  3. sorl6.0+jetty+mysql

    sorl6.0+jetty+mysql搭建solr服务 1.下载solr 官网:http://lucene.apache.org/solr/ v2.目录结构如下 v3.启动solr(默认使用jetty ...

  4. 这些屌炸天的创业者为何对投资人说NO

    曾有人说,世上的创业者只分为两种,一种是找到投资的,一种是没有找到的. 但其实还有第三种,就是那些拒绝了投资人的创业者. 他们摒弃了投资人抛来的橄榄枝,并非不差钱,不接受投资的原因大体出于两个方面,一 ...

  5. Android项目增加混淆

    主要介绍向Android项目中添加混淆功能 增加混淆的原因 提高安全性,增加反编译的难度 减少APK的文件大小 实践 混淆的配置 一般情况下,app module 的 build.gradle 文件默 ...

  6. [WPF疑难]Hide me! not close

    原文 [WPF疑难]Hide me! not close [WPF疑难]Hide me! not close                               周银辉 有朋友遇到这样的一个问 ...

  7. MAC Eclipse 快捷键

    MAC Eclipse 快捷键大全备忘: Command + O:显示大纲 Command + 1:快速修复 Command + D:删除当前行 Command + Option + ↓:复制当前行到 ...

  8. 从PyOpenCV到CV2

    安装cv2 http://hyry.dip.jp/files/opencv.zip 采用cv2重写的<Python科学计算>中的实例程序 读者可以在下面的页面中搜索“opencv”,并根据 ...

  9. wiki oi 1044 拦截导弹

    题目描述 Description 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某 ...

  10. codility上的练习 (1)

    codility上面添加了教程.目前只有lesson 1,讲复杂度的……里面有几个题, 目前感觉题库的题简单. tasks: Frog-Jmp: 一只青蛙,要从X跳到Y或者大于等于Y的地方,每次跳的距 ...