不是什么时候都可以用栈来声明对象并使用(自动释放)——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 ...
随机推荐
- python中os.walk浏览目录和文件
#!/usr/bin/env python # 2.py # use UTF-8 # Python 3.3.0 # os.walk()的使用 import os # 枚举dirPath目录下的所有文件 ...
- linux 进程通信
IPC: 管道,FIFO,信号,消息队列(system v/ posix),共享内存(system v/ posix),socket 同步机制: 互斥锁,条件变量,记录上锁, 信号量(system ...
- java如何把char型数据转换成int型数据(转)
一字符串,String=“2324234535”:把第i个数取出来时是char型的:char temp=String.charAt(i)如何把char型转换成int型?我需要求个尾数之和,如:123的 ...
- perl学习(5) 输入和输出
1.1. 从标准输入设备输入 <STDIN> 行输入操作在到达文件的结尾时将返回undef,在while循环的条件中不能使用chomp: while (defined($line = &l ...
- java基础知识----IO篇
写在前面:本文章基本覆盖了java IO的所有内容.java新IO没有涉及.文章依然以样例为主,由于解说内容的java书非常多了,我觉的学以致用才是真.代码是写出来的,不是看出来的. 最后欢迎大家提出 ...
- 【Maven】项目添加Maven类库依赖
1.右击项目-->Maven-->EnableDependencyManagement,按步骤完成操作. 2.右击项目-->Properties-->DeploymentAss ...
- CodeForces 486C Palindrome Transformation 贪心+抽象问题本质
题目:戳我 题意:给定长度为n的字符串,给定初始光标位置p,支持4种操作,left,right移动光标指向,up,down,改变当前光标指向的字符,输出最少的操作使得字符串为回文. 分析:只关注字符串 ...
- XML IList<T> TO DataSet TO DataTable 相互转换
//遍历XML 获得 DataSet //XmlTextReader static void Main(string[] args) { string xmlData = @"D:\stud ...
- 浙江工商大学15年校赛E题 无邪的飞行棋 【经典背包】
无邪的飞行棋 Time Limit 1s Memory Limit 64KB Judge Program Standard Ratio(Solve/Submit) 15.38%(4/26) Descr ...
- u-boot分析——struct gd_t与struct bd_t
gd_t和bd_t是u-boot中两个重要的数据结构,在初始化操作很多都要靠这两个数据结构来保存或传递.分别定义在./include/asm/global_data.h和./include/asm/u ...