QScopedPointer
QScopedPointer 是 Qt 框架中提供的一个智能指针类,其核心目的是为了管理动态分配的对象的生命周期。它保证在 QScopedPointer 所在的作用域结束时自动删除其管理的对象,从而帮助防止内存泄漏。它类似于 C++11 的 std::unique_ptr,但不支持 C++11 的移动语义
1.特点:
- 自动资源管理:QScopedPointer 自动释放它所持有的对象,确保资源得到合理的管理。
- 所有权:QScopedPointer 对象拥有严格的所有权管理,即它不允许复制或赋值,确保一个对象只有一个拥有者。
- 作用域限定:QScopedPointer 确保只在定义它的局部作用域内有效,出了作用域就会自动释放所管理的资源。
2.常用方法:
- reset():删除当前对象,接受一个新的对象指针以管理。如果不传递参数,则简单地删除当前对象并将指针置为 nullptr
- data():返回一个指向所管理对象的裸指针,不改变所有权
- take():释放对对象的所有权并返回对象的裸指针,QScopedPointer 随后不再管理任何对象
- isNull():检查 QScopedPointer 是否为空(即是否指向 nullptr)
- 操作符重载:允许使用->访问所持有的对象,就像普通指针一样
使用示例
class MyClass {
public:
void display() { qDebug() << "Displaying MyClass"; }
};
void scopedPointerExample() {
QScopedPointer<MyClass> ptr(new MyClass);
ptr->display(); // 访问通过 operator->()
ptr.reset(new MyClass()); // 重置指针,自动删除旧对象
if (!ptr.isNull()) {
ptr->display();
}
MyClass* raw = ptr.take(); // 取出裸指针,ptr 现在为空
if (ptr.isNull()) {
qDebug() << "Pointer is now null.";
}
delete raw; // 手动删除对象
}
QSharedPointer
QSharedPointer 是 Qt 库中提供的一个引用计数型智能指针。它用于管理动态分配的对象的生命周期,通过跟踪指向同一个对象的所有 QSharedPointer 实例的数量来实现。当最后一个这样的智能指针被销毁或重置时,所管理的对象也会被自动删除
1.特点
- 引用计数:内部通过引用计数来确保只有最后一个指针被销毁时,对象才会被删除
- 线程安全:QSharedPointer 的引用计数机制是线程安全的,适用于多线程环境
- 自动资源管理:自动管理所指向的对象,防止内存泄漏
- 复制和赋值:允许复制和赋值操作,复制时引用计数会增加,赋值时先减少原有对象的引用计数,可能导致原有对象的删除
这里特别说明一下线程安全这个问题,在官方文档中翻了一下大概意思是这样的:
QSharedPointer 的线程安全性体现在其引用计数的增加和减少操作上。在多线程环境中,如果多个线程同时对同一个 QSharedPointer 对象执行引用计数的增加和减少操作,Qt 会确保这些操作的原子性,避免了竞态条件和数据竞争。官方文档地址
2.常用方法
- reset():重置智能指针,可以指定新的对象或者重置为 nullptr
- data():返回管理的对象的裸指针,但不改变所有权
- isNull():检查智能指针是否为空
- clear():等同于 reset(),将内部指针置为 nullptr
- 操作符重载:允许使用->访问所持有的对象,就像普通指针一样
- toStrongRef(): 返回一个新的 QSharedPointer
- toWeakRef() :返回一个 QWeakPointer,后者可以用来避免循环引用问题。
使用示例:
class MyClass {
public:
MyClass() { qDebug() << "MyClass created"; }
~MyClass() { qDebug() << "MyClass destroyed"; }
void display() const { qDebug() << "Displaying MyClass"; }
};
void sharedPointerExample() {
QSharedPointer<MyClass> ptr1(new MyClass()); // 对象创建
{
QSharedPointer<MyClass> ptr2 = ptr1; // 引用计数增加
ptr2->display(); // 通过 ptr2 访问对象
} // ptr2 出作用域,引用计数减少
ptr1->display(); // 对象仍然存在,可以通过 ptr1 访问
} // ptr1 出作用域,引用计数为 0,对象被销毁
QWeakPointer
QWeakPointer 是 Qt 库中的一种智能指针,用于在不增加对象引用计数的情况下,持有对由 QSharedPointer 管理的对象的非拥有(弱)引用。它可以防止循环引用问题,并且当原始 QSharedPointer 不再存在时,QWeakPointer 不会保持对象存活,而是变得无效
1.使用场景:
- 防止循环引用:当使用 QSharedPointer 并且对象之间相互引用,可以用QWeakPointer 打破循环引用,防止内存泄漏
-暂时引用:当你需要引用一个对象,但不需要该对象因此而保持活跃时,使用 QWeakPointer
使用示例
class MyClass {
public:
MyClass() { qDebug() << "MyClass created"; }
~MyClass() { qDebug() << "MyClass destroyed"; }
};
void testWeakPointer() {
QWeakPointer<MyClass> weak;
{
QSharedPointer<MyClass> strong = QSharedPointer<MyClass>(new MyClass);
weak = strong;
if (weak.toStrongRef()) {
qDebug() << "Object is still alive";
}
}
if (!weak.toStrongRef()) {
qDebug() << "Object has been destroyed";
}
}