Qt为何new而不delete

本篇首先介绍一下Qt的内存管理机制,其为QObject类的三大职责之一,QObject的另外两个职责为内省和事件处理。
Qt是基于C++的应用框架,平时,我们释放一个指针资源一般采用new和delete相结合的方法,比如:我们生成一个label,代码如下:
                      QLabel *MyLabel=new QLabel("hello, QT!");
等我们不必使用这个label的时候,可以用如下方法释放内存:
                       delete Mylabel;
用过Qt的程序员都不会对你的第一个程序Hello Qt陌生,我们在一个窗口上显示一个label,label上的内容是“hello Qt!”,采用Qt4版本,其主要代码如下:
#include  QApplication  
#include  QLabel  
int main (int argc, char *argv[])
{
         QApplication a(argc, argv);
         label *Mylabel=new QLabel("hello, Qt");
         return a.exec();
}
程序运行起来,一切输出正常,这里为什么没有delete MyLabel语句呢? 这是因为这部分代码尽管有内存泄漏,但是对整个程序影响不大,在程序结束时,可以由操作系统重新收回。
       然而,Qt自身还有一套内存回收机制,这种机制并不像JAVA那样对垃圾自动回收,主要依靠QObject类的职责:Qt的对象都要继承QObject,这个类保存有一个父指针和子对像集合,当此Qt对象析构时,它会自动析构所有子对象。如下代码, 只用指明父对象,便可在父对象被delete时自动清理:
#include QApplication
#include QLabel
int main (int argc, char *argv[])
{
         QApplication a(argc, argv);
         label *Mylabel=new QLabel("hello, Qt",this);
         return a.exec();
}
 QT的这套回收内存的机制,主要的规则如下:
  1.所有继承自QOBJECT类的类,如果在new的时候指定了父亲,那么它的清理时在父亲被delete的时候delete,所以如果一个程序中,所有的QOBJECT类都指定了父亲,那么他们是会一级级的在最上面的父亲清理时被清理,而不用自己清理;
  2.程序通常最上层会有一个根的QOBJECT,就是放在setCentralWidget()中的那个QOBJECT,这个QOBJECT在 new的时候不必指定它的父亲,因为这个语句将设定它的父亲为总的QAPPLICATION,当整个QAPPLICATION没有时它就自动清理,所以也无需清理。
  3.如果我们自己释放掉设置QObject为自己父亲的类,那个指向的父亲的QObject会从自己的儿子列表把这个儿子的删除掉,就不会出现儿子的内存会被释放两次,如果我们要删除有这种关系的QObject类的话,正常情况,这样它会将这个儿子移出它的列表,并且重新构建显示内容,但是直接这样做时有风险的!
  4.当一个QOBJECT正在接受事件队列时如果中途被你DELETE掉了,就是出现问题了,所以QT中建议大家不要直接DELETE掉一个 QOBJECT,如果一定要这样做,要使用QOBJECT的deleteLater()函数,它会让所有事件都发送完一切处理好后马上清除这片内存,而且就算调用多次的deletelater也不会有问题。
   5.QT不建议在一个QOBJECT 的父亲的范围之外持有对这个QOBJECT的指针,因为如果这样外面的指针很可能不会察觉这个QOBJECT被释放,会出现错误。
   6.QT中的智能指针封装为QPointer类,所有QOBJECT的子类都可以用这个智能指针来包装,很多用法与普通指针一样。
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值