智能指針類模板(五十)

        咱們以前在 C++ 的學習中學習了有關智能指針的知識。那麼智能指針的意義是現代 C++ 開發庫中最重要的類模板之一;是 C++ 中自動內存管理的主要手段,它可以在很大程度上避開內存相關的問題。在 STL 標準庫中的智能指針爲 auto_ptr,它的特色是:一、生命週期結束時,銷燬指向的內存空間;二、不能指向堆數組,只能指向堆對象(變量);三、一片堆空間只屬於一個智能指針對象;四、多個智能指針對象不能指向同一片堆空間ios

        下來咱們就來使用下 auto_ptr 智能指針數組

#include <iostream>
#include <string>
#include <memory>

using namespace std;

class Test
{
    string m_name;
public:
    Test(const char* name)
    {
        cout << "Hello, " << name << "!" << endl;
        
        m_name = name;
    }
    
    void print()
    {
        cout << "I'm " << m_name << "!" << endl;
    }
    
    ~Test()
    {
        cout << "Goodbye, " << m_name << "!" << endl;
    }
};

int main()
{
   auto_ptr<Test> pt(new Test("D.T.Software"));
   
   cout << "pt = " << pt.get() << endl;
   
   pt->print();
   
   cout << endl;
   
   auto_ptr<Test> pt1(pt);
   
   cout << "pt = " << pt.get() << endl;
   cout << "pt1 = " << pt1.get() << endl;
   
   pt1->print();
    
    return 0;
}

        咱們定義了一個類 Test 用來講明問題。在 main 函數中先是用 auto_ptr 指針來建立了一個指向 Test 類的指針,通過下面這個指針 pt1 的操做後,pt 指針會指向空了。咱們來看看編譯結果ide

圖片.png

        咱們看到在通過指針 pt1 指向 pt 操做以後,指針 pt 的值便爲空了。並且咱們也沒有 delete,它便會自動的去刪除指針,執行了析構函數。下來咱們再來講說 STL 標準庫中的其它智能指針:a> shared_ptr,帶有引用計數機制,支持多個指針對象指向同一片內存;b> weak_ptr,配合 shared_ptr 而引入的一種智能指針;c> unique_ptr,一個指針對象指向一片內存空間,不能拷貝構造和賦值。函數

        下來咱們再來看看 QT 中的智能指針:a> QPointer,當其指向的對象被銷燬時,它會被自動置空,可是它析構時不會自動銷燬所指向的對象;b> QSharedPointer,引用計數型智能指針,能夠被自由地拷貝和賦值,當引用計數爲 0 時才刪除指向的對象。咱們仍是以 QT 中的代碼爲例來進行分析(跟 C++ 差很少)學習

#include <QPointer>
#include <QSharedPointer>
#include <QDebug>

class Test : public QObject
{
    QString m_name;
public:
    Test(const char* name)
    {
        qDebug() << "Hello, " << name << "!";

        m_name = name;
    }

    void print()
    {
        qDebug() << "I'm " << m_name << "!";
    }

    ~Test()
    {
        qDebug() << "Goodbye, " << m_name << "!";
    }
};

int main()
{
    QPointer<Test> pt(new Test("D.T.Software"));
    QPointer<Test> pt1(pt);
    QPointer<Test> pt2(pt);

    pt->print();
    pt1->print();
    pt2->print();

    delete pt;

    qDebug() << endl;

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

    QSharedPointer<Test> spt(new Test("David"));
    QSharedPointer<Test> spt1(spt);
    QSharedPointer<Test> spt2(spt);

    spt->print();
    spt1->print();
    spt2->print();

    return 0;
}

        在 QT 中的輸出是用 QDebug,它裏面的字符串是用 QString 表示。咱們在 QPointer 類中是手動調用 delete 的,而在 QSharedPointer 並無去調用 delete。來看看編譯結果圖片.pngthis

        咱們看到已經實現了。在刪除了 QPointer 類後,它的三個指針都指向爲空了。這便有效的防止了內存泄漏和野指針的操做了。那麼咱們介紹了這麼多的智能指針後,咱們再基於咱們以前建立的智能指針,在它的基礎上本身再來實現一個智能指針類模板。spa


SmartPointer.h 源碼指針

#ifndef _SMARTPOINTER_H_
#define _SMARTPOINTER_H_

template
< typename T >
class SmartPointer
{
    T* mp;
public:
    SmartPointer(T* p = NULL)
    {
        mp = p;
    }
    
    SmartPointer(const SmartPointer<T>& obj)
    {
        mp = obj.mp;
        const_cast<SmartPointer<T>&>(obj).mp = NULL;
    }
    
    SmartPointer<T>& operator = (const SmartPointer<T>& obj)
    {
        if( this != &obj )
        {
            delete mp;
            mp = obj.mp;
            const_cast<SmartPointer<T>&>(obj).mp = NULL;
        }
        
        return *this;
    }
    
    T* operator -> ()
    {
        return mp;
    }
    
    T& operator * ()
    {
        return *mp;
    }
    
    bool isNull()
    {
        return (mp == NULL);
    }
    
    T* get()
    {
        return mp;
    }
    
    ~SmartPointer()
    {
        delete mp;
    }
};

#endif


test.cpp 源碼對象

#include <iostream>
#include <string>
#include "SmartPointer.h"

using namespace std;

class Test
{
    string m_name;
public:
    Test(const char* name)
    {
        cout << "Hello, " << name << "!" << endl;
        
        m_name = name;
    }
    
    void print()
    {
        cout << "I'm " << m_name << "!" << endl;
    }
    
    ~Test()
    {
        cout << "Goodbye, " << m_name << "!" << endl;
    }
};

int main()
{
    SmartPointer<Test> pt(new Test("D.T.Software"));

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

    pt->print();

    cout << endl;

    SmartPointer<Test> pt1(pt);

    cout << "pt = " << pt.get() << endl;
    cout << "pt1 = " << pt1.get() << endl;

    pt1->print();

    return 0;
}

        咱們在 main 函數沒有改動,只是將 auto_ptr 指針改成咱們本身實現的 SmartPointer 了,再來看看是否是和以前的效果是同樣的呢?生命週期

圖片.png

        經過對智能指針類模板的學習,總結以下:一、智能指針是 C++ 中自動內存管理的主要手段;二、智能指針在各類平臺上都有不一樣的表現形式;三、智能指針可以儘量的避開內存相關的問題;四、STL 和 Qt 中都提供了對智能指針的支持


        歡迎你們一塊兒來學習 C++ 語言,能夠加我QQ:243343083

相關文章
相關標籤/搜索