Table of Contents

Qt的垃圾回收机制


通过父子关系进行回收

在写Qt的界面的时候,创建一个空间都是通过new操作,但是不需要delete操作(如果编写正确的话),那么内存是如何回收的呢?Qt的垃圾回收机制其实很好理解,那就是建立父子关系,也就是从属关系,每个Widget有一个父对象,也维护这一个子对象的列表,当父对象析构的时候,那么子对象也应该被回收了,所以自然而然的,由父对象负责回收子对象,所以只要一个Widget有父对象,并且其父对象一直向上寻找能找到一个会被回收的对象,比如是一个自动存储类型的变量等,那么这个对象就是安全的,不会泄漏内存,不需要手动delete。

UI中不需要指定父子关系

如上文所述,为了实现自动回收,每个Widget都要设定父对象,在编写UI的时候,还会使用到Layout,Layout也需要回收内存,所以也需要有父对象,这一点和Widget是相同的。和Widget不同的是,Layout不能作为Widget的父对象,Widget的父对象只能是Widget。

每个QObject创建的时候,都可以通过传递父对象的指针给构造函数这样的方式指定父对象,但是在编写UI的时候,我强烈不建议这样。那么应该什么时候指定父对象呢?父对象的指定可以发生在以下情况:

那么根据以上规律,谁需要我们手动指定父对象呢?

为什么我说强烈不建议在构造函数中指定父对象?

Widget还好,在构造函数中指定了父对象,后面可以继续更换父对象,而Layout指定父对象不一定能成功,如果指定的父Widget已经有了Layout,那么指定就会不成功,需要把Widget之前指定的Layout先删除掉才行。一个Widget只需要指定一个Layout就行,在逻辑上来说本来也不需要指定多次,所以我们把这个操作拿出来,自己手动进行指定,更清晰。

如何维护的父子关系?

维护父对象很容易,指定哪个为父对象就保存就行了,但是注意子对象的维护,自己指定父对象后:

总结来说就是,只能有一个父对象,不能被多个父对象共享,树形的结构。

被引用的指针

因为Qt的回收机制是树型的,所以即使在不是UI的地方,只要被引用到了的指针(被引用的时候,可能就关联了父子关系),不是独立的指针,都可以被回收。