C++ 使用智能指針shared_ptr/unique_ptr管理數組


關於shared_ptr/unique_ptr的基礎,我不在本篇博客中贅述。本篇博客主要關注如何安全地使用智能指針來管數組。

零、要管理的類

Connection是一個管理連接的類。

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

class Connection{
public:
    Connection():_name(""){}
    Connection(string name):_name(name){
    }
    string get_name() const {
        return _name;
    }
    ~Connection(){
        cout << string("關閉")+get_name()+"管理的連接中..." << endl;
        //關閉連接的代碼
        // .....
        cout << "關閉完成。" << endl;
    }
private:
    string _name;
};

一、使用shared_ptr管理數組

給出一個例子:

int main(){
    Connection* c1 = new Connection[2]{string("s1"), string("s2")};
    // 新建管理連接Connection的智能指針
    shared_ptr<Connection> sp(c1);
}

運行輸出:

關閉s1管理的連接中...
munmap_chunk(): invalid pointer
關閉完成。

Process finished with exit code 134 (interrupted by signal 6: SIGABRT)

可以發現,只有s1被正確釋放了,s2沒有被成功釋放。因爲shared_ptr默認是使用delete來釋放管理的資源,delete只會調用第一個元素的析構函數,所以只有s1被正確析構了(delete[ ] 會依次調用數組元素的析構函數)。要使用shared_ptr來管理數組,就需要需要自定義刪除器(參考鏈接)。

int main(){
    auto Deleter=[](Connection *connection){
        delete[] connection;
    };
    Connection* c1 = new Connection[2]{string("s1"), string("s2")};
    // 新建管理連接Connection的智能指針
    shared_ptr<Connection> sp(c1, Deleter);
}

二、使用unique_ptr管理數組

1、第一種方式

unique_ptr可以像shared_ptr一樣使用刪除器來釋放管理的數組。

int main(){
    auto Deleter=[](Connection *connection){
        delete[] connection;
    };
    Connection* c1 = new Connection[2]{string("c1"), string("c2")};
    // 新建管理連接Connection的智能指針
    unique_ptr<Connection, decltype(Deleter)> up(c1, Deleter);
}

2、第二種方式

unique_ptr重載了管理數組的版本,使用方法如下:

int main(){
    Connection* c1 = new Connection[2]{string("c1"), string("c2")};
    // 新建管理連接Connection的智能指針
    unique_ptr<Connection[]> up(c1);
}

模板參數“Connection”後面還有“[]”。 unique_ptr就會自動使用delete[]來釋放c1。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章