Qt智能指针--QScopedPointer
文章目錄
- 概述
- 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)題。
- 上一篇: Qt+VS2013编译报错:'cl' 不
- 下一篇: Qt智能指针--QSharedPoint