Qt深入浅出(三)Qt的内存管理机制

小灰灰 2023-07-13 15:08 35阅读 0赞

4 内存管理机制

  • 一般我们不直接用QWidget来实例化对象,用它的派生类来生成对象,main函数中一般不写太多代码,都是在派生类的构造函数中进行窗口的初始化、布局、设置、其子窗口设置等等。

例如:

main.cpp

  1. #include <QApplication>
  2. #include "widget.h"
  3. int main(int argc, char** argv)
  4. {
  5. QApplication app(argc, argv);
  6. Widget widget;
  7. widget.show();
  8. return app.exec();
  9. }

widget.h

  1. #ifndef WIDGET_H
  2. #define WIDGET_H
  3. #include <QWidget>
  4. class Widget : public QWidget
  5. {
  6. public:
  7. Widget( QWidget * parent = 0); //继承QWidget或者其派生类的时候,一般要实现带一个QWidget*参数的构造函数,用来指定其父窗口的对象。
  8. };
  9. #endif

widget.cpp

  1. #include "widget.h"
  2. #include <QPushButton>
  3. Widget::Widget(QWidget *parent) : QWidget(parent)
  4. {
  5. this->resize(400, 300);
  6. this->move(100, 100);
  7. }
  • 构造函数中要用new来申请堆窗口对象,不能使用栈对象, 因为栈对象生命周期只在构造函数内,构造函数执行完成后,栈对象就被销毁了,于是看不到该窗口。

    以下是错误的写法:

    include “widget.h”

    include

    Widget::Widget(QWidget *parent) : QWidget(parent)
    {

    1. this->resize(400, 300);
    2. this->move(100, 100);
    3. QPushButton pb;
    4. pb.setParent(this);

    }

以下是正确写法:

  1. #include "widget.h"
  2. #include <QPushButton>
  3. Widget::Widget( QWidget * parent) : QWidget( parent)
  4. {
  5. this -> resize( 400, 300);
  6. this -> move( 100, 100);
  7. QPushButton pb * = new QPushButton;
  8. pb -> setParent( this);
  9. }
  • 我们看到以上正确代码只有new而没有delete,难道是课件代码写错了?我是否还要在析构函数里delete呢?

    ​ 其实是Qt有一套回收内存的机制,子窗口可以通过指定父窗口,来托管子窗口内存的释放,而父窗口又通过它的父窗口来销毁对象,顶级窗口一般在main函数中实例化为可自动销毁的栈对象,子窗口无需进行额外的释放。

    ​ 我们可以通过派生一个子窗口类,然后分别在父子窗口析构函数里打印信息,来观察子窗口的释放过程。

  • 是不是只有窗口类对象有这套管理机制,还是所有的Qt类都可以使用这套管理机制?

    ​ 所有的QObject派生类都可以通过指定父对象进行内存托管,QWidget继承至QObject,所以它能使用这套管理机制,后面我们还会接触到其它的QObject派生类对象,例如QGraphicsItem,它也可以使用这套内存管理机制。

  • 那么所有的子对象只能在父对象销毁的时候才能一起销毁,势必造成内存持续占用,能不能我们自己来销毁呢?

    ​ 当然,开发者可以使用delete来释放QObject对象,但是不推荐这么使用,QObject对象远比普通的类要复杂的多,QObject底层实现在我们不知道的情况下,正进行着一些工作。如果这个时候使用delete强制释放,会造成不可预知的错误。

    ​ 一般我们会使用deleteLater函数,进行安全释放,它会等待对象所有事情都处理完毕后才释放。

    1. [ slot] void QObject::deleteLater();

发表评论

表情:
评论列表 (有 0 条评论,35人围观)

还没有评论,来说两句吧...

相关阅读