大宇私人领地伊甸园丨宁愿做了后悔,也不要错过后悔[www.mrdayu.com]
注册

24小时联系邮箱:[email protected]

所有文章
大宇私人伊甸园: 首页 > 所有文章 > 编程人生 > 系统架构 > QT > 《大宇的Qt学习笔记》 > [002.07]Qt内存回收机制

[002.07]Qt内存回收机制

发布时间:2018/05/31 《大宇的Qt学习笔记》 标签Qt内存回收机制阅读:207

前言:

关于 Qt 内存回收机制的,刚接触 Qt 不久,第一次看到这方面的问题。这篇文章需要在对Qt有很多了解后才会理解的更透彻。在你不断补充知识时,温故而知新。看到更全面和更官方的内容时随时更新。

内容:

Qt's parent–child mechanism is implemented in QObject. 
When we create an object (a widget, validator, or any other kind) with a parent, the parent adds the object to the list of its children. 
When the parent is deleted, it walks through its list of children and deletes each child. 
The children themselves then delete all of their children, and so on recursively until none remain. 
The parent–child mechanism greatly simplifies memory management, reducing the risk of memory leaks. 
The only objects we must call delete on are the objects we create with new and that have no parent. 
And if we delete a child object before its parent, Qt will automatically remove that object from the parent's list of children.

在 C++ Primer 中读到 new 是在堆里面申请一段内存资源,new 必须与 delete 成对使用,否则就会造成内存泄漏。

但是在Qt中经常可以看见只 new 而不 delete 的情况,这并没有错,Qt 的内存管理机制允许这样的情况存在。

1、所有继承自 QOBJECT 类的类,如果在 new 的时候指定了父亲,那么它的清理时在父亲被 delete 的时候 delete 的。
2、程序通常最上层会有一个根的 QOBJECT ,就是放在 setCentralWidget() 中的那个 QOBJECT ,
这个 QOBJECT 在 new 的时候不必指定它的父亲,因为这个语句将设定它的父亲为总的 QAPPLICATION ,
当整个 QAPPLICATION 没有时它就自动清理,所以也 无需清理。
(这里 QT4 和 QT3 有不同,QT3 中用的是 setmainwidget 函数,但是这个函数不作为里面 QOBJECT 的父亲,所以 QT3 中这个顶层的 QOBJECT 要自行销毁)。
3、这时有人可能会问那如果我自行 delete 掉这些 QT 接管负责销毁的指针了会出现什么情况呢,如果是这样的话,
正常情况下 QT 的拥有这个对象的那个父亲会知道这件事情,
它会知道它的儿子被你直接 DELETE 了,这样它会将这个儿子移出它的列表,
并且重新构建显示内容,但是直接这样做是有风险的! 也就是要说的下一条
4、当一个 QOBJECT 正在接受事件队列时如果中途被你 DELETE 掉了,
就时就出现问题了,所以 QT 中建议大家不要直接DELETE 掉一个 QOBJECT ,
如果一定要这样做,要使用 QOBJECT 的 deleteLater() 函数,
它会让所有事件都发送完一切处理好后马上清除这片内存,而且就算调用多次的 deletelater 也不会有问题。
5、QT 不建议在一个 QOBJECT 的父亲的范围之外持有对这个 QOBJECT 的指针,
因为如果这样外面的指针很可能不会察觉这个 QOBJECT 被释放,会出现错误,如果一定要这样,
就要记住你在哪这样做了,然后抓住那个被你违规使用的 QOBJECT 的destroyed()信号,
当它没有时赶快置零你的外部指针。当然我认为这样做是极其麻烦也不符合高效率编程规范的,
所以如果要这样在外部持有 QOBJECT 的指针,建议使用引用或者用智能指针,
如QT就提供了智能指针针对这些情况,见最后 一条。
6、QT 中的智能指针封装为 QPointer 类,所有 QOBJECT 的子类都可以用这个智能指针来包装,
很多用法与普通指针一样,可以详见 QT assistant 通过调查这个QT的内存管理功能,发现了很多东西,现在觉得虽然这个QT弄的有点小复杂,但是使用起来还是很方便的, 最后要说的是某些内存泄露的检测工具会认为 QT 的程序因为这种方式存在内存泄露,发现时大可不必理会。 原来是因为 qt 对 c++ 的内存管理机制进行了扩充,所有继承自 QObject 的类 new 出来的成员都会自动delete,而手动delete反而会造成不必要的麻烦。 在c++中如果不手动delete,new对象的内存在进程结束后才会被系统回收,在运行是占用内存越来越多,这就是内存泄露。
The bottom line, for me, is simple.

Let’s hope it doesn’t take 500 years for a discipline of testing to becomes the standard for software developers.

From:dayu
相关推荐

您好!请登录

合作网站快捷登录:
点击取消回复

已有1评论

    大宇博客

    点击这里给我发消息 点击这里给我发消息 点击这里给我发消息 点击这里给我发消息