溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

C++智能指針類模板

發(fā)布時間:2020-07-09 22:59:23 來源:網(wǎng)絡(luò) 閱讀:2010 作者:小溢 欄目:編程語言



1、智能指針本質(zhì)上是一個對象,這個對象可以像原生的一樣來進(jìn)行使用。原因是智能指針對象對應(yīng)的類中,將指針相關(guān)的操作都進(jìn)行了重載操作處理,所以才會達(dá)到這種像是原生的效果。


2、智能指針的意義:

現(xiàn)在C++開發(fā)庫中最重要的類模板之一

C++中自動內(nèi)存管理的主要手段

能夠在很大程度上避開內(nèi)存相關(guān)的問題


3、在QT中開發(fā)庫中也提供了智能指針類模板,在STL標(biāo)準(zhǔn)庫中也提供了,在c++的標(biāo)準(zhǔn)庫忘了什么名了中也提供了智能指針類模板。所以智能指針類模板在C++中的地位很重要


4、STL中的智能指針類模板 auto_ptr,在memory這個頭文件中。


(1)生命周期結(jié)束時,銷毀指向的內(nèi)存空間


(2)不能指向堆數(shù)組,只能指向堆對象(變量)


(3)一片堆空間只屬于一個智能指針對象


(4)多個智能指針對象不能指向同一片堆空間


既然auto_ptr是一個類模板,所以使用時就要指定類型參數(shù)。如a:auto_ptr<Test> pt(new Test()); pt.get();可以返回pt所指向的空間的內(nèi)存起始地址.


5、STL中的其他智能指針 


(1)shared_ptr:帶有引用計數(shù)機(jī)制,所以可以支持多個指針對象指向同一片內(nèi)存空間


(2)weak_ptr:配合shared_ptr而引人的一種智能指針


(3)unique_ptr:一個指針對象只能指向一片內(nèi)存空間,但是不能進(jìn)行所有權(quán)的轉(zhuǎn)移,所以就不能拷貝構(gòu)造和賦值。



例:STL標(biāo)準(zhǔn)庫中auto_ptr的使用


#include <iostream>

#include <string>

#include <memory> //auto_ptr這個智能指針類模板就在這個頭文件中


using namespace std;


/*

* STL標(biāo)準(zhǔn)庫中的auto_ptr智能指針類模板的使用。

* auto_ptr的特點:

* 生命周期結(jié)束時,銷毀指向的內(nèi)存空間

* 不能指向堆數(shù)組,只能指向堆對象(變量)

* 一片堆空間只屬于一個智能指針對象

* 多個智能指針對象不能指向同一片堆空間

*/



class Test

{

private:

string m_name;

public:

Test(const char *name)

{

m_name = name;

cout << "Hello." << "I'm " << name << endl; 

}

void print()

{

cout << "why_fangqingqing " << endl;

}

~Test()

{

cout << "Goodbye " << m_name << endl;

}

};


int main(void)

{

auto_ptr<Test> pt1(new Test("why"));

cout << "pt1 = " << pt1.get() << endl; //獲取指向的內(nèi)存空間的起始地址

pt1->print();

auto_ptr<Test> pt2(pt1); //pt2指向了pt1指向的內(nèi)存空間,pt1釋放掉指向的內(nèi)存空間,這是auto_ptr的特點,一片內(nèi)存空間只能由一個auto_ptr指針對象指向

cout << "pt1 = " << pt1.get() << endl; // 0

cout << "pt2 = " << pt2.get() << endl;

pt2->print();

return 0;

}



6、Qt中的智能指針類模板


(1)QPointer,在Qt中包含QPointer頭文件就可以使用這個QPointer智能指針類模板了


@1:當(dāng)其指向的對象被銷毀時,它會被自動置空。(也就是說可以多個QPointer智能指針指向同一個對象,當(dāng)這個對象被銷毀的時候,所有的指向這個對象的QPointer指針都變?yōu)榭樟耍?/p>


@2:析構(gòu)時不會自動銷毀所指向的對象。(也就是說QPoniter指針生命周期結(jié)束的時候,不會自動刪除所指向的對象(堆空間),我們要手動的delete掉,手動delete一次之后,所有指向這個堆

空間的QPointer指針都會被置為空)


(2)QSharedPointer,在Qt中的QSharedPointer頭文件中。


@1:引用計數(shù)型智能指針


@2:可以被自由的拷貝和賦值


@3:當(dāng)引用計數(shù)為0時才刪除指向的對象(也就是,當(dāng)這個對象被一次QSharedPointer指針指向時,就會加一次這個對象的引用的次數(shù)。當(dāng)指向這個對象的QSharedPointer指針少一個時,

就會減一次這個對象的引用次數(shù),直到減到?jīng)]有一個QSharedPointer指針指向這個對象時,也就是這個對象被QSharedPointer指針引用次數(shù)為0時,才會銷毀這個對象)


在Qt開發(fā)中,所有自己寫的類,都要去繼承QObject這個頂層父類,也就是基類。


7、Qt中的其他智能指針類模板


(1)QWeakPointer


(2)QScopedPointer


(3)QSharedDataPointer


(4)QExplicitlySharedDataPointer



例:


#include <QPointer>

#include <QSharedPointer>

#include <QString>

#include <QDebug>


/*

* Qt開發(fā)庫中的QPointer智能指針和QSharedPo智能指針類模板的使用。

* QPointer的特點:

* @1:當(dāng)其指向的對象被銷毀時,它會被自動置空。

*  (也就是說可以多個QPointer智能指針指向同一個對象,當(dāng)這個對象被銷毀的時候,所有的指向這個對象的QPointer指針都變?yōu)榭樟耍?/p>

* @2:析構(gòu)時不會自動銷毀所指向的對象。(也就是說QPoniter指針生命周期結(jié)束的時候,

* 不會自動刪除所指向的對象(堆空間),我們要手動的delete掉,手動delete一次之后,所有指向這個堆空間的QPointer指針都會被置為空)

*/


/*

*   QSharedPointer的特點:

*   @1:引用計數(shù)型智能指針

*   @2:可以被自由的拷貝和賦值

*   @3:當(dāng)引用計數(shù)為0時才刪除指向的對象(也就是,當(dāng)這個對象被一次QSharedPointer指針指向時,就會加一次這個

*   對象的引用的次數(shù)。當(dāng)指向這個對象的QSharedPointer指針少一個時,就會減一次這個對象的引用次數(shù),

*   直到減到?jīng)]有一個QSharedPointer指針指向這個對象時,也就是這個對象被QSharedPointer指針引用次數(shù)為0時,才會銷毀這個對象)

*/


class Test : public QObject //Qt中所有自己完成的類都要繼承這個Qt中的QObject頂層父類,基類

{

private:

    QString m_name;

public:

    Test(const char *name)

    {

        m_name = name;


        qDebug() << "Hello." << "I'm " << name;

    }


    void print()

    {

        qDebug() << "why_fangqingqing ";

    }


    ~Test()

    {

        qDebug() << "Goodbye " << m_name;

    }

};


int main(void)

{

    QPointer<Test> pt1(new Test("why"));

    QPointer<Test> pt2(pt1);


    qDebug() << "pt1 = " << pt1;

    qDebug() << "pt2 = " << pt2;


    pt1->print();

    pt2->print();


    delete pt1; //要手動的去delete掉pt1所指向的堆空間。編譯器不會自動的去銷毀,當(dāng)生命周期結(jié)束時,delete掉后,所有指向這個空間

                //的QPointer指針都會被置為空。

    qDebug() << "pt1 = " << pt1;    //0

    qDebug() << "pt2 = " << pt2;    //0


    qDebug() << endl;


    QSharedPointer<Test> spt1(new Test("fangqingqing"));    //這時這個堆空間的對象被QSharedPoin引用了一次

    QSharedPointer<Test> spt2(spt1);    //這時這個堆空間的對象被QSharedPoin引用又加了一次


    qDebug() << "spt1 = " << spt1;

    qDebug() << "spt2 = " << spt2;


    spt1->print();

    spt2->print();


    return 0;       //當(dāng)那個堆空間的對象被QSharedPointer引用的次數(shù)減到0時,就會銷毀這個堆空間的對象

}




7、自己實現(xiàn)一個智能指針類模板



#ifndef _SMARTPOINTER_H_

#define _SMARTPOINTER_H_


template

< typename T >

class Pointer

{

private:

T *mp;

public:

Pointer(T* p = NULL)

{

mp = p;

}

Pointer(const Pointer<T>& obj)

{

mp = obj.mp;

const_cast<Pointer<T>&>(obj).mp =NULL;

}

Pointer<T>& operator = (const Pointer<T>& obj)

{

if (this != &obj)

{

delete mp;

mp = obj.mp;

const_cast<Pointer<T>&>(obj).mp = NULL;

}

return *this;

}

T* get()

{

return mp;

}

T* operator -> ()

{

return mp;

}

T& operator * ()

{

return *mp;

}

~Pointer()

{

delete mp;

}

bool isNULL()

{

return (mp == NULL);

}

};



#endif


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI