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<MyClass> p(useSubClass ? new MyClass() : new MySubClass);QScopedPointer<QIODevice> device(handsOverOwnership());if (m_value > 3)return;process(device);}注意:因為拷貝構造和賦值操作私有的,所以不能用作容器的元素。
const 限制
C ++指針的const限定也可以用QScopedPointer表示:
const QWidget *const p = new QWidget();// 等同于:const QScopedPointer<const QWidget> p(new QWidget());QWidget *const p = new QWidget();// 等同于:const QScopedPointer<QWidget> p(new QWidget());const QWidget *p = new QWidget();// 等同于:QScopedPointer<const QWidget> p(new QWidget());考慮一種情況
上面說到,使用QScopedPointer智能指針動態創建的對象,一旦出了作用域就會 被自動釋放并置空,那么如果需要函數返回值怎么辦呢?
比如下面這種情況:
QLabel * createLabel() {QScopedPointer<QLabel> pLabel(new QLabel()); // return pLabel.data(); //invalidreturn pLabel.take(); //valid }int main(int argc, char *argv[]) {QApplication a(argc, argv);QScopedPointer<QLabel> 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<int> i(new int[10]);i[2] = 42;...return; // our integer array is now deleted using delete[]}超出作用域過后會自動調用delete[]刪除指針,這里就不展開描述了。
總結
以上是生活随笔為你收集整理的Qt智能指针--QScopedPointer的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Qt+VS2013编译报错:'cl' 不
- 下一篇: Qt智能指针--QSharedPoint