關於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。