日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Qt智能指针--QScopedPointer

發(fā)布時(shí)間:2025/1/21 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Qt智能指针--QScopedPointer 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

    • 概述
    • QScopedPointer
    • const 限制
    • 考慮一種情況
    • QScopedArrayPointer

概述

前一篇文章我們?cè)敿?xì)的介紹了QPointer的用法,那么,這里繼續(xù)總結(jié)Qt的另一個(gè)智能指針QScopedPointer的用法。

QScopedPointer和C++中的智能指針std::unique_ptr其概念是一樣的,它包裝了new操作符在堆上分配的動(dòng)態(tài)對(duì)象,能夠保證動(dòng)態(tài)創(chuàng)建的對(duì)象在任何時(shí)候都可以被正確地刪除。但它有更嚴(yán)格的所有權(quán),并且不能轉(zhuǎn)讓,一旦獲取了對(duì)象的管理權(quán),你就無(wú)法再?gòu)乃抢锶』貋?lái)。也就是說(shuō),只要出了作用域,指針就會(huì)被自動(dòng)刪除,因?yàn)樗目截悩?gòu)造和賦值操作都是私有的,與QObject及其派生類風(fēng)格相同。

QScopedPointer

首先我們來(lái)看一個(gè)官方示例:

沒(méi)有使用智能指針:

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; }

上面的寫法,稍有不慎就會(huì)導(dǎo)致內(nèi)存泄露,但是如果使用智能指針,就會(huì)變得很簡(jiǎn)單了:

void myFunction(bool useSubClass){QScopedPointer<MyClass> p(useSubClass ? new MyClass() : new MySubClass);QScopedPointer<QIODevice> device(handsOverOwnership());if (m_value > 3)return;process(device);}

注意:因?yàn)榭截悩?gòu)造和賦值操作私有的,所以不能用作容器的元素。

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());

考慮一種情況

上面說(shuō)到,使用QScopedPointer智能指針動(dòng)態(tài)創(chuàng)建的對(duì)象,一旦出了作用域就會(huì) 被自動(dòng)釋放并置空,那么如果需要函數(shù)返回值怎么辦呢?

比如下面這種情況:

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(); }

注意,我們?cè)赾reateLabel()函數(shù)中創(chuàng)建label對(duì)象并返回時(shí),不能使用data(),而要使用take();
因?yàn)?T *QScopedPointer::data() const返回指向?qū)ο蟮某A恐羔?#xff0c;QScopedPointer仍擁有對(duì)象所有權(quán)。 所以通過(guò)data()返回過(guò)后就被自動(dòng)刪除了,從而導(dǎo)致mian函數(shù)中的p1變成了野指針,程序崩潰。
而使用T *QScopedPointer::take()也是返回對(duì)象指針,但QScopedPointer不再擁有對(duì)象所有權(quán),而是轉(zhuǎn)移到調(diào)用這個(gè)函數(shù)的caller,同時(shí)QScopePointer對(duì)象指針置為NULL。

另外還有一個(gè)函數(shù)要注意。
void QScopedPointer::reset(T *other = Q_NULLPTR):delete目前指向的對(duì)象,調(diào)用其析構(gòu)函數(shù),將指針指向另一個(gè)對(duì)象other,所有權(quán)轉(zhuǎn)移到other。

QScopedArrayPointer

對(duì)應(yīng)的還有一個(gè)指針QScopedArrayPointer,專門用于處理數(shù)組,其用法和QScopedPointer是一樣的

官方簡(jiǎn)單示例:

void foo(){QScopedArrayPointer<int> i(new int[10]);i[2] = 42;...return; // our integer array is now deleted using delete[]}

超出作用域過(guò)后會(huì)自動(dòng)調(diào)用delete[]刪除指針,這里就不展開(kāi)描述了。

總結(jié)

以上是生活随笔為你收集整理的Qt智能指针--QScopedPointer的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。