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

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. VJGUI消息设计-兼谈MFC、QT和信号/槽机制

    星期六下午4点,还在公司加班.终于写完了下周要交工的一个程序. 郁闷,今天这几个小时写了有上千行代码吧?虽然大部分都是Ctrl-C+Ctrl-V,但还是郁闷. 作为一个有10年经验的MFC程序员,郁闷 ...

  2. Runtime.getRuntime().exec(...)使用方法

    Runtime.getRuntime().exec(...)使用方法 如果想要了解更多的信息,参阅代码里面给的链接  下面是这个正确的例子 public class RuntimeExec { /** ...

  3. linux shell 执行多个命令的方法

    (1)在每个命令之间用:(分号)隔开. (2)在每个命令之间用&&隔开. &&表示:若前一个命令执行成功,才会执行下一个.这样,可确保所有的命令执行完毕后,其执行过程都 ...

  4. asp.net将object或string转为int

    在C#强制转换中,(int),Int32.Parse() 和 Convert.toInt32() 三种方法有何区别? int 关键字表示一种整型,是32位的,它的 .NET Framework 类型为 ...

  5. 爬虫框架Scrapy

    前面十章爬虫笔记陆陆续续记录了一些简单的Python爬虫知识, 用来解决简单的贴吧下载,绩点运算自然不在话下. 不过要想批量下载大量的内容,比如知乎的所有的问答,那便显得游刃不有余了点. 于是乎,爬虫 ...

  6. VC++非MFC项目中如何使用TRACE宏

    记得原来尝试学MFC的时候觉得有一个TRACE可以在Debug时向VS的调试输出窗口输出字串符,用来调试时跟踪变量很方便. 然则如果不是MFC项目或者ATL的项目的话是不能使用这个宏的.这时有一个没有 ...

  7. android音乐柱状频谱实现

    from: http://blog.csdn.net/topgun38/article/details/7663849 原文地址:http://blog.csdn.net/caryee89/artic ...

  8. 【MongoDB】windows平台搭建Mongo数据库复制集(相似集群)(一)

    Replica  Sets(复制集)是在mongodDB1.6版本号開始新增的功能.它能够实现故障自己主动切换和自己主动修复功能成员节点的功能,各个DB之间的数据全然一致,大大减少了单点故障的风险. ...

  9. stm32之USART通信

    任何USART通信,需要用到2个对外连接的引脚:RxD,TxD: RxD是输入引脚,用于串行数据接收: TxD是输出引脚,用于串行数据发送: SCLK引脚:发生器时钟输出(同步模式下,异步模式下不需要 ...

  10. json接口相关(建议结合JFinal框架)

    /** * */ package net.wicp.wvqusrtg; import java.util.HashMap; import net.sf.json.JSONArray; import n ...