网站首页 > 技术文章 正文
前言
Qt智能指针QSharedPointer 与 C++中的std::shared_ptr其作用是一样的,其应用范围比我们前面说到的QPointer和QScopedPointer更广。
QSharedPointer
QSharedPointer 是一个共享指针,它与 QScopedPointer 一样包装了new操作符在堆上分配的动态对象,但它实现的是引用计数型的智能指针 ,也就是说,与QScopedPointer不同的是,QSharedPointer可以被自由地拷贝和赋值,在任意的地方共享它,所以QSharedPointer也可以用作容器元素。
所谓的计数型指针,就是说在内部QSharedPointer对拥有的内存资源进行引用计数,比如有3个QSharedPointer同时指向一个内存资源,那么就计数3,直到引用计数下降到0,那么就自动去释放内存啦。
需要注意的是:QSharedPointer 是线程安全的,因此即使有多个线程同时修改 QSharedPointer 对象也不需要加锁。虽然 QSharedPointer 是线程安全的,但是 QSharedPointer 指向的内存区域可不一定是线程安全的。所以多个线程同时修改 QSharedPointer 指向的数据时还要应该考虑加锁。
先来看一个官方示例:
static void doDeleteLater(MyObject *obj)
{
obj->deleteLater();
}
void otherFunction()
{
QSharedPointer<MyObject> obj =
QSharedPointer<MyObject>(new MyObject, doDeleteLater);
// continue using obj
obj.clear(); // calls obj->deleteLater();
}
这个示例中,传入了一个函数,用于自定义删除。
也可以直接使用成员函数:
QSharedPointer<MyObject> obj =
QSharedPointer<MyObject>(new MyObject, &QObject::deleteLater);
QSharedPointer使用非常方便,直接和普通指针用法一样,创建后直接用,后面就不用管了。
再来看一个自己写的简单示例:
class Student : public QObject
{
Q_OBJECT
public:
Student(QObject * parent = nullptr);
~Student();
};
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = 0);
~Widget();
private:
QSharedPointer<Student> m_pStudent;
};
#include "widget.h"
#include <QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
qDebug() << __FUNCTION__;
m_pStudent = QSharedPointer<Student>(new Student());
}
Widget::~Widget()
{
qDebug() << __FUNCTION__;
}
Student::Student(QObject *parent):
QObject (parent)
{
qDebug() << __FUNCTION__;
}
Student::~Student()
{
qDebug() << __FUNCTION__;
}
运行后关闭窗口,输出:
Widget
Student
~Widget
~Student
可以看到,student对象被自动释放了。
值得一提
我们都知道Qt的QObject对象树系统(父子),当在创建对象时如果指定了父对象,那么该对象就无需手动释放,会由父对象去做资源回收。我在查询智能指针相关资料的时候,看到一篇文章,介绍智能指针和QObject对象树系统结合使用的时候,程序会崩溃,文章在这里,不过这是六年前的博客了。我尝试了一下,结果并没有出现崩溃的情况:
还是上面的示例,改动如下:
m_pStudent = QSharedPointer<Student>(new Student(this));
在new的时候指定了父对象
运行过后关闭窗口,很正常。我使用的是Qt5.11.1
说明,这些年Qt的更新解决了这个问题。那么我们在用的过程中就可以少些顾虑了,放心使用。
点击领取Qt学习资料+视频教程~
链接:http://docs.qq.com/doc/DUlVwTW1FZlZuWE9G
猜你喜欢
- 2024-10-24 QT(17)- QNetworkAccessManager qnetworkinterface.allinterfaces
- 2024-10-24 Qt多线程的三种方法QThread qt多线程直接处理数据
- 2024-10-24 从零开始学Qt(86):TCP服务器端程序设计
- 2024-10-24 Qt Core学习日记——第九天QObjectData
- 2024-10-24 QT(11)- QThread qt ui thread work thread
- 2024-10-24 Qt QVariant的用法 qt基本语法
- 2024-10-24 Qt5中QOverload的用法 qt5coredll
- 2024-10-24 Qt多线程编程之QThread qt中的多线程
- 2024-10-24 Qt QModbusReply类 qty是什么单位的缩写
- 2024-10-24 Qt Core学习日记——第十一天QObject(下)
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- oraclesql优化 (66)
- 类的加载机制 (75)
- feignclient (62)
- 一致性hash算法 (71)
- dockfile (66)
- 锁机制 (57)
- javaresponse (60)
- 查看hive版本 (59)
- phpworkerman (57)
- spark算子 (58)
- vue双向绑定的原理 (68)
- springbootget请求 (58)
- docker网络三种模式 (67)
- spring控制反转 (71)
- data:image/jpeg (69)
- base64 (69)
- java分页 (64)
- kibanadocker (60)
- qabstracttablemodel (62)
- java生成pdf文件 (69)
- deletelater (62)
- com.aspose.words (58)
- android.mk (62)
- qopengl (73)
- epoch_millis (61)
本文暂时没有评论,来添加一个吧(●'◡'●)