QSharedPointer 智能指针 引用计数 共享所有权,类似于C++的std::shared_ptr
使用方法
1.创建QSharedPointer:
QSharedPointer<MyObject> obj = QSharedPointer<MyObject>(new MyObject);
2.复制和赋值:
QSharedPointer<MyObject> obj2 = obj; // 引用计数增加
3.释放内存:当最后一个指向对象的QSharedPointer
被销毁或者引用计数变为0时,对象内存自动释放。
obj.clear(); // 显式地将引用计数减为0并释放内存
4.自定义删除器:可以传递删除器函数或成员函数作为第二个参数,以自定义对象的删除方式。
void doDeleteLater(MyObject *obj) { obj->deleteLater(); }
QSharedPointer<MyObject> obj = QSharedPointer<MyObject>(new MyObject, doDeleteLater);
注意事项
- 线程安全:
QSharedPointer
本身是线程安全的,多个线程可以同时修改QSharedPointer
对象而不需要加锁。 - 指向数据的线程安全:尽管
QSharedPointer
是线程安全的,但它指向的内存区域不一定是线程安全的。如果多个线程需要同时修改QSharedPointer
指向的数据,仍需要考虑加锁。
线程安全的QSharedPointer示例
一个简单的Data
类,多个线程会访问和修改它的数据。使用QSharedPointer
来管理Data
实例的生存期,使用互斥锁来保护数据免受并发访问影响。
class Data {
public:
//...
void updateData(int value) {
QMutexLocker locker(&mutex_); // 自动锁定互斥锁
data_ = value;
}
int getData() const {
QMutexLocker locker(&mutex_); // 自动锁定互斥锁
return data_;
}
private:
mutable QMutex mutex_; // 用于保护数据的互斥锁
int data_;
};
// 在某个线程中安全地使用QSharedPointer<Data>
QSharedPointer<Data> sharedData = QSharedPointer<Data>(new Data);
sharedData->updateData(42); // 线程安全地更新数据
// 在另一个线程中
int value = sharedData->getData(); // 线程安全地获取数据
Data
类的updateData
和getData
方法使用QMutexLocker
自动管理互斥锁,确保同一时间只有一个线程可以访问或修改data_
成员。即使QSharedPointer
本身是线程安全的,但是通过额外的锁保护数据,确保了多线程环境下的安全性。