shared_ptr簡介
shared_ptr是一個**标準的共享所有權的智能指針。**它允許多個指針指向同一個對象,定義在memory檔案内,命名空間為std。
shared_ptr最初實作于Boost庫中,後由C++11引入到C++ STL。
shared_ptr利用引用計數的方式實作了對所管理的對象的所有權的分享,即:
- 允許多個shared_ptr共同管理同一個對象。
shared_ptr是為了解決auto_ptr在對象所有權上的局限性而提出的(auto_ptr是獨占的),使用引用計數的機制的同時,提供了可共享所有權的智能指針。這種額外的機制,需要額外的代價:
- shared_ptr對象除了包括一個所擁有的對象的指針外,還必須包括一個引用計數代理對象的指針。
- 時間上,開銷主要消耗在初始化和拷貝操作上。
shared_ptr的使用
shared_ptr多個指針指向同一個對象,每一個shared_ptr的拷貝都會指向相同的記憶體。
- 每使用一次,内部的引用計數就加一;
- 每析構一次,内部的引用次數就減一;當減為0時,将會自動删除所指向的堆記憶體。
shared_ptr内部的引用計數是線程安全的,但是對象的讀取需要加鎖。
- 初始化。智能指針是一個模闆類,可以指定類型,傳入指針并通過構造函數初始化。也可以通過make_shared函數初始化。不能将指針直接指派給一個智能指針,因為一個是類,一個是指針。例如,
的寫法就是錯誤的。shared_ptr<int> p = new int(1);
- 拷貝與指派。拷貝操作使得對象的引用計數增加1,指派操作使得原對象引用計數減一,當計數為0是,自動釋放記憶體。
- get函數用于擷取原始指針。
- 不能用一個原始指針初始化多個shared_ptr,否則會造成二次釋放同一記憶體。
- 注意避免循環引用。shared_ptr的一個最大的陷阱就在于循環引用,循環、循環引用将會導緻堆記憶體無法正确釋放,進而導緻記憶體洩漏。
#include <iostream>
#include <memory>
int main()
{
int a = 10;
std::shared_ptr<int> ptra = std::make_shared<int>(a);
std::shared_ptr<int> ptra2(ptra); //copy
std::cout << ptra.use_count() << std::endl;
int b = 20;
int *pb = &a;
//std::shared_ptr<int> ptrb = pb; //error
std::shared_ptr<int> ptrb = std::make_shared<int>(b);
ptra2 = ptrb; //assign
pb = ptrb.get(); //擷取原始指針
std::cout << ptra.use_count() << std::endl;
std::cout << ptrb.use_count() << std::endl;
}
參考文章:
C++11中智能指針的原理、使用、實作