Qt智能指针--QScopedPointer
文章目录
- 概述
- QScopedPointer
- const 限制
- 考虑一种情况
- QScopedArrayPointer
概述
前一篇文章我们详细的介绍了QPointer的用法,那么,这里继续总结Qt的另一个智能指针QScopedPointer的用法。
QScopedPointer和C++中的智能指针std::unique_ptr其概念是一样的,它包装了new操作符在堆上分配的动态对象,能够保证动态创建的对象在任何时候都可以被正确地删除。但它有更严格的所有权,并且不能转让,一旦获取了对象的管理权,你就无法再从它那里取回来。也就是说,只要出了作用域,指针就会被自动删除,因为它的拷贝构造和赋值操作都是私有的,与QObject及其派生类风格相同。
QScopedPointer
首先我们来看一个官方示例:
没有使用智能指针:
void myFunction(bool useSubClass)
{MyClass *p = useSubClass ? new MyClass() : new MySubClass;QIODevice *device = handsOverOwnership();if (m_value > 3) {delete p;delete device;return;}try {process(device);}catch (...) {delete p;delete device;throw;}delete p;delete device;
}
上面的写法,稍有不慎就会导致内存泄露,但是如果使用智能指针,就会变得很简单了:
void myFunction(bool useSubClass){QScopedPointer p(useSubClass ? new MyClass() : new MySubClass);QScopedPointer device(handsOverOwnership());if (m_value > 3)return;process(device);}
注意:因为拷贝构造和赋值操作私有的,所以不能用作容器的元素。
const 限制
C ++指针的const限定也可以用QScopedPointer表示:
const QWidget *const p = new QWidget();// 等同于:const QScopedPointer p(new QWidget());QWidget *const p = new QWidget();// 等同于:const QScopedPointer p(new QWidget());const QWidget *p = new QWidget();// 等同于:QScopedPointer p(new QWidget());
考虑一种情况
上面说到,使用QScopedPointer智能指针动态创建的对象,一旦出了作用域就会 被自动释放并置空,那么如果需要函数返回值怎么办呢?
比如下面这种情况:
QLabel * createLabel()
{QScopedPointer pLabel(new QLabel());
// return pLabel.data(); //invalidreturn pLabel.take(); //valid
}int main(int argc, char *argv[])
{QApplication a(argc, argv);QScopedPointer p1(createLabel());p1->setText("hello");p1->show();return a.exec();
}
注意,我们在createLabel()函数中创建label对象并返回时,不能使用data(),而要使用take();
因为 T *QScopedPointer::data() const返回指向对象的常量指针,QScopedPointer仍拥有对象所有权。 所以通过data()返回过后就被自动删除了,从而导致mian函数中的p1变成了野指针,程序崩溃。
而使用T *QScopedPointer::take()也是返回对象指针,但QScopedPointer不再拥有对象所有权,而是转移到调用这个函数的caller,同时QScopePointer对象指针置为NULL。
另外还有一个函数要注意。
void QScopedPointer::reset(T *other = Q_NULLPTR):delete目前指向的对象,调用其析构函数,将指针指向另一个对象other,所有权转移到other。
QScopedArrayPointer
对应的还有一个指针QScopedArrayPointer,专门用于处理数组,其用法和QScopedPointer是一样的
官方简单示例:
void foo(){QScopedArrayPointer i(new int[10]);i[2] = 42;...return; // our integer array is now deleted using delete[]}
超出作用域过后会自动调用delete[]删除指针,这里就不展开描述了。
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
