Qt 内存管理 #

对象树机制 #

基本概念 #

cpp
// Qt 的对象树自动管理内存
QWidget *window = new QWidget;

// 子对象指定父对象
QPushButton *button = new QPushButton("Click", window);
QLabel *label = new QLabel("Text", window);

// 父对象删除时,子对象自动删除
delete window;  // button 和 label 也被删除

设置父对象 #

cpp
// 构造时指定父对象
QObject *child = new QObject(parent);

// 使用 setParent
child->setParent(parent);

// 获取父对象
QObject *p = child->parent();

// 获取所有子对象
QList<QObject*> children = parent->children();

查找子对象 #

cpp
// 按名称查找
QObject *child = parent->findChild<QObject*>("childName");

// 查找所有匹配的子对象
QList<QPushButton*> buttons = parent->findChildren<QPushButton*>();

智能指针 #

QSharedPointer #

cpp
#include <QSharedPointer>

// 创建共享指针
QSharedPointer<MyClass> ptr = QSharedPointer<MyClass>::create();
QSharedPointer<MyClass> ptr2(new MyClass());

// 共享所有权
QSharedPointer<MyClass> ptr3 = ptr;

// 使用
ptr->doSomething();

// 自动删除

QWeakPointer #

cpp
// 弱引用,不增加引用计数
QWeakPointer<MyClass> weak = ptr;

// 检查是否有效
if (!weak.isNull()) {
    QSharedPointer<MyClass> strong = weak.toStrongRef();
    if (strong) {
        strong->doSomething();
    }
}

QPointer #

cpp
#include <QPointer>

// 用于 QObject 派生类
QPointer<QWidget> widget = new QWidget;

// 检查是否有效
if (widget) {
    widget->show();
}

// 当对象被删除时,自动变为 nullptr

QScopedPointer #

cpp
#include <QScopedPointer>

// 作用域指针,离开作用域自动删除
void myFunction()
{
    QScopedPointer<MyClass> ptr(new MyClass);
    ptr->doSomething();
    // 函数结束时自动删除
}

// 自定义删除器
QScopedPointer<FILE, QScopedPointerPodDeleter> file(fopen("test.txt", "r"));

内存泄漏预防 #

常见问题 #

cpp
// 问题 1:忘记删除
QWidget *widget = new QWidget;  // 没有 parent,忘记 delete

// 问题 2:重复删除
QWidget *widget = new QWidget;
delete widget;
delete widget;  // 错误!

// 问题 3:悬空指针
QWidget *widget = new QWidget;
QWidget *ptr = widget;
delete widget;
ptr->show();  // 错误!

解决方案 #

cpp
// 方案 1:使用对象树
QWidget *widget = new QWidget(parent);

// 方案 2:使用栈对象
QWidget widget;  // 自动销毁

// 方案 3:使用智能指针
QSharedPointer<QWidget> widget = QSharedPointer<QWidget>::create();

// 方案 4:使用 QPointer
QPointer<QWidget> widget = new QWidget;
if (widget) {
    widget->show();
}

deleteLater #

cpp
// 安全延迟删除
widget->deleteLater();

// 在事件循环中删除
// 避免在信号槽中直接删除对象

最佳实践 #

推荐做法 #

cpp
// 1. 控件使用对象树
QPushButton *button = new QPushButton("Text", parentWidget);

// 2. 非控件对象使用智能指针
QSharedPointer<DataModel> model = QSharedPointer<DataModel>::create();

// 3. 临时对象使用栈
QString text = "Hello";

// 4. 大对象使用堆
QImage *image = new QImage;  // 配合智能指针

下一步 #

现在你已经掌握了内存管理,接下来学习 性能优化,了解 Qt 应用的性能优化技巧!

最后更新:2026-03-29