一、引入
1.QT实现输出"hello world"
使用QT编写"hello world"程序,有两种实现方式:
(1)直接在生成的ui文件中,拖入一个label控件,双击控件编辑内容即可实现
(2)通过代码方式实现
2.控件对象创建方式
在创建控件对象时,我们可以使用QLabel obj的方式直接在栈上创建,也可以用new的方式在堆上创建。
在上图中可以看到,在创建label控件时是通过new在堆上创建的方式,并且没有进行手动释放,但这并不会造成内存泄漏问题,这是因为在创建该控件时,我还传入了一个this参数,这其实就是将该对象挂载到了QT的对象树中,将其生命周期交给对象树来进行统一管理。
所以在实际使用中,更推荐以new的方式进行创建。
3.为什么推荐new的方式创建
如果控件对象是在栈上创建,可能产生一些提前释放的问题,导致控件无法正常显示等问题,例如:
二、对象树
1.概念
对象树是QT在内存中组织所有QT对象的一种数据结构,对象树的根节点是QObject,其子类对象是子节点,子对象在父对象被删除时自动被删除。
2.优点
(1)将QT对象以树的形式组织起来,更方便管理;
(2)可以实现对象之间的通信,使得他们可以互相之间发送信号和槽函数;
(3)可以实现对象的继承,使得子类对象可以继承父类对象的属性和方法;
(4)一定程度上简化了内存管理。
3.验证
我们可以自己定义一个MyLabel类,创建对象来观察对象的创建释放过程:
(1)新建一个C++文件,可以让其继承自QLabel
(2)编写MyLabel.h
#ifndef MYLABEL_H
#define MYLABEL_H
#include <QLabel>
class MyLabel : public QLabel
{
public:
// 构造函数添加上QWidget*参数
// 确保对象能够添加到对象树上
MyLabel(QWidget* parent);
~MyLabel();
};
#endif // MYLABEL_H
(3)在析构函数中,添加日志输出
#include "mylabel.h"
#include <iostream>
MyLabel::MyLabel(QWidget* parent):QLabel(parent)
{
}
MyLabel::~MyLabel()
{
std::cout << "MyLabel destroy" << std::endl;
}
(4)构造MyLabel对象
(5)运行程序,"hello world"正常显示
(6)关闭窗口,查看是否输出日志信息
(7)存在日志信息,说明其析构函数在窗口销毁时被调用。