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