qt智能指標介紹

來源:互聯網
上載者:User

簡介

Qt提供了很多智能指標,比較常見的有QPointer, QSharedDataPointer ,QSharedPointer,QWeakPointer和QScopedPointer。

描述

QPointer (4.0)  已經過時,可以被QWeakPointer所替代,它不是安全執行緒的。

QSharedDataPointer (4.0) 提供對資料的COPY-ON-WRITE以及淺拷貝,提供對資料線程安

全的保護。(註:提供對資料的安全執行緒保護要結合QsharedData來完成),它是安全執行緒的。

QSharedPointer (4.5)   實現了引用計數的可共用資源的強型別指標,它是安全執行緒的。有著與std::auto_ptr類似的特性,而最大的區別在於它不能轉讓所有權而auto_ptr可以。

QWeakPointer (4.5)    實現了引用計數的可共用資源的弱類型指標,它是安全執行緒的。

QScopedPointer (4.6)   實現了非引用計數的獨享資源的強型別指標,它是安全執行緒的。

strong pointer :      在有它所指向的資源的所有權期間,永遠不會放棄這個所有權。

weak pointer:在有它所指向的資源的所有權期間,允許外界釋放其資源從而使其放棄這個所有權。

詳解

QScopedPointer 與 std::unique_ptr

它們概念上應當是是一樣的。下面不再區分:

這是一個很類似auto_ptr的智能指標,它封裝了new操縱符在堆上指派的動態對象,包管動態建立的對象在任何時候可以被正確地刪除。但它的所有權加倍嚴格,一旦擷取了對象的經管權,你就無法再從它那邊取回來。

無論QScopedPointer 還是 std::unique_ptr 都擁有一個很好的名字,它向代碼的瀏覽者傳遞了明白的資訊:這個智能指標只能在本感化域裡應用,不能被轉讓。因為它的拷貝機關和賦值操縱都是私人的,這點我們可以對比QObject及其衍生類別的對象哈。

重視:因為拷貝機關和賦值操縱私人的,它也具有auto_ptr同樣的“缺點”——不能用作容器的元素。

QSharedPointer 與 std::shared_ptr

QSharedPointer 與 std::shared_ptr 行動最接近原始指標,是最像指標的"智能指標",應用局限比前面的提到的更廣。

QSharedPointer 與 QScopedPointer 一樣封裝了new操縱符在堆上指派的動態對象,但它實現的是引用計數型的智能指標 ,可以被自由地拷貝和賦值,在隨便率性的處所共用它,當沒有代碼應用(引用計數為0)它時才刪除被封裝的動態指派的對象。shared_ptr也可以安然地放 到標準容器中,並彌補了std::auto_ptr 和 QScopedPointer 因為轉移語義而不能把指標作為容器元素的缺點。

boost::shared_ptr的管理機制其實並不複雜,就是對所管理的對象進行了引用計數,當新增一個boost::shared_ptr就將該對象的引用計數加一;少一個boost::shared_ptr就將該對象的引用計數減一,如果該對象的引用計數為0的時候,說明沒有任何指標對其管理,才調用delete釋放其所佔的記憶體。(參見執行個體二)

和前面介紹的boost::scoped_ptr相比,boost::shared_ptr可以共用對象的所有權,因此其使用範圍基本上沒有什麼限制(還是有一些需要遵循的使用規則,下文中介紹),自然也可以使用在stl的容器中。另外它還是安全執行緒的,這點在多線程程式中也非常重要。

boost::shared_ptr的使用規則:

避免對shared_ptr所管理的對象的直接記憶體管理操作,以免造成該對象的重釋放。

shared_ptr並不能對循環參考的對象記憶體自動管理(這點是其它各種引用計數管理記憶體方式的通病)。

不要構造一個臨時的shared_ptr作為函數的參數。

如下列代碼則可能導致記憶體流失:

void test()

{

    foo(boost::shared_ptr<implementation>(new    implementation()),g());

}

正確的用法為:

void test()

{

    boost::shared_ptr<implementation> sp    (new implementation());

    foo(sp,g());

}

QWeakPointer 與 std::weak_ptr

強參考型別的QSharedPointer已經很是好用,為什麼還要有弱引用的 QWeakPointer?

QWeakPointer 是為共同 QSharedPointer 而引入的一種智能指標,它更像是 QSharedPointer 的一個助手(因為它不具有通俗指標的行動,沒有重載operator*和->)。它的最鴻文用在於協助 QSharedPointer 工作,像一個觀察遲疑者一樣來觀測資料的應用景象。

weak_ptr 主如果為了避免強引用形成環狀。

在Qt中,對於QObject及其衍生類別對象,QWeakPointer有特別處理懲罰。它可以作為QPointer的調換品

QSharedDataPointer

這是為共同 QSharedData 實現隱式共用(寫時複製 copy-on-write))而供給的便利對象。

Qt中浩繁的類都應用了隱式共用技巧,比如QPixmap、QByteArray、QString、...。而我們為本身的類實現隱式共用也很簡單,比如要實現一個 Employee類:
定義一個只含有一個資料成員(QSharedDataPointer<EmployeeData>) 的 Employee 類
我們須要的所稀有據成員放置於派生自QSharedData的 EmployeeData類中。

QExplicitlySharedDataPointer

這是為共同 QSharedData 實現顯式共用而供給的便利對象。

QExplicitlySharedDataPointer 和 QSharedDataPointer 很是類似,然則它禁用了寫時複製功能。這使得我們建立的對象更像一個指標。

一個例子,接前面的Employee:

 #include "employee.h"

 int main()  

{     

  Employee e1(1001, "Albrecht Durer");      

      Employee e2 = e1;      

e1.setName("Hans Holbein");  

}

寫時複製技巧導致:e1和e2有雷同的工號,但有不合名字。與我們等待的不合,顯式共用可以解決這個題目,這也使得Employee本身更像一個指標。

執行個體解析

執行個體一

1 int main(int argc, char *argv[])     

2 {     

3     QCoreApplication a(argc, argv);     

4     //raw pointer     

5     QString *p = new QString("hello");     

6     //Implements non-reference-counted strong pointer     

7     QScopedPointer<QString> pScopedPointer(new QString("Scoped"));     

8     // Build error, can NOT be shared and reference-counted     

9     //QScopedPointer<QString> pScopedPointerpScopedPointer2 = pScopedPointer;     

10     //Implements reference-counted strong sharing of pointers     

11     QSharedPointer<QString> pSmart(new QString("Smart"));     

12     QSharedPointer<QString> pSmart2;     

13     pSmart2 = QSharedPointer<QString>(new QString("smart 2"));     

14     QSharedPointer<QString> pSharedPoninter;     

15     // can be shared safely and reference-counted     

16     pSharedPoninter = pSmart;     

17     qDebug() << *(pSmart.data());     

18     qDebug() << *(pSmart2.data());     

19     qDebug() << *(pSharedPoninter.data());     

20     QTimer *timer = new QTimer();     

21     QWeakPointer<QTimer> pWeakPointer = timer;     

22     //Weak pointer's resources can be deleted from outside world     

23     delete timer;     

24     if (pWeakPointer.isNull())     

25     {     

26         qDebug() << "contained QObject has been deleted";     

27     }     

28 }   

執行個體二

#include <string>

#include <iostream>

#include <boost/shared_ptr.hpp>

class implementation

{

public:

    ~implementation() { std::cout <<"destroying implementation\n"; }

    void do_something() { std::cout << "did something\n"; }

};

void test()

{

    boost::shared_ptr<implementation> sp1(new implementation());

    std::cout<<"The Sample now has "<<sp1.use_count()<<" references\n";

    boost::shared_ptr<implementation> sp2 = sp1;

    std::cout<<"The Sample now has "<<sp2.use_count()<<" references\n"; 

    sp1.reset();

    std::cout<<"After Reset sp1. The Sample now has "<<sp2.use_count()<<" references\n";

    sp2.reset();

    std::cout<<"After Reset sp2.\n";

}

void main()

{

    test();

}

該程式的輸出結果如下:

The Sample now has 1 references

The Sample now has 2 references

After Reset sp1. The Sample now has 1 references

destroying implementation

After Reset sp2.

可以看到,boost::shared_ptr指標sp1和sp2同時擁有了implementation對象的存取權限,且當sp1和sp2都釋放對該對象的所有權時,其所管理的的對象的記憶體才被自動釋放。在共用對象的存取權限同時,也實現了其記憶體的自動管理。

參考文獻

http://mobile.51cto.com/symbian-272817.htm

http://www.mysjtu.com/page/M0/S670/670782.html

http://blog.csdn.net/lmh12506/article/details/8897015

http://blog.csdn.net/txb70780533/article/details/5385516

Qt助手

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.