//make_shared分配一塊int型別大小的記憶體,並值初始化為100
//返回值是shared_ptr型別,因此可以直接賦值給sp
shared_ptr sp = make_shared(100);
//錯誤! 不會進行隱式轉換,型別不符合
shared_ptr sp1 = new int(100);
//正確,直接初始化呼叫建構函式
shared_ptr sp2(new int(100000));
分配好了記憶體空間,我們就可以使用shared_ptr定義的操作了
多個共享指標指向同乙個空間,它們的關係可能是關聯(我們所期望的正常關係)或是獨立的(一種錯誤狀態)
shared_ptr sp1(new int(10));
shared_ptr sp2(sp1), sp3;
sp3 = sp1;
//乙個典型的錯誤用法
shared_ptr sp4(sp1.get());
cout << sp1.use_count() << " " << sp2.use_count() << " "
<< sp3.use_count() << " " << sp4.use_count() << endl;
//輸出 3 3 3 1
sp1,sp2,sp3是相互關聯的共享指標,共同控制所指記憶體的生存期,sp4雖然指向同樣的記憶體,卻是與sp1,sp2,sp3獨立的,sp4按自己的引用計數來關聯記憶體的釋放。
只有用乙個shared_ptr為另乙個shared_ptr賦值時,才將這連個共享指標關聯起來,直接使用位址值會導致各個shared_ptr獨立。有時候我們需要用智慧型指標管理非new的物件,或者是沒有析構函式的類,由於shared_ptr預設使用delete來釋放記憶體並執行析構函式,對於以上的兩種情況是不適用的,所以我們要傳遞特別的刪除器
刪除器必須接受單個型別為 t* 的引數
//沒有析構函式的類
struct mystruct
//建構函式中申請了一塊記憶體
//用裸指標管理,不用時需要手動釋放
};void main()
); }
// 離開作用域,呼叫傳遞的刪除器釋放sp所指的記憶體空間
}
對於以上這個例子,首先不可以用delete來釋放區域性物件,然後mystruct也沒有析構函式來釋放申請的空間,所以向管理它的shared_ptr傳遞乙個刪除器來做這兩件事。
關於獨立的shared_ptr的意思及危害上面已經說出,遵守下面幾點來避免這個錯誤
不要與裸指標混用
//錯誤場景1
int *x(new int(10));
shared_ptr sp1(x);
shared_ptr sp2(x);
//雖然sp1、sp2都指向x所指的記憶體,但他們是獨立的,
//會在其他shared_ptr還在使用記憶體的情況下就釋放掉記憶體
//失去了設計共享指標的意義
//同時,使用裸指標x本身也是很危險的,x隨時可能變成空懸指標而無從知曉
//錯誤場景2
//函式接受乙個共享指標引數
void func(shared_ptr sp);
int *x(new int(10));
//建立了乙個指向x指標所指記憶體的共享指標,引用計數為1,是引用這塊記憶體的唯一共享指標
func(shared_ptr (x));
//離開函式即離開共享指標的作用域,這塊記憶體即被刪除
不要用p.get()的返回值為shared_ptr賦值
shared_ptr sp1(new int(10));
//sp2與sp1獨立
shared_ptr sp2(sp1.get()),sp3;
//sp3與sp1獨立
sp.reset(sp1.get());
p.get()的返回值就相當於乙個裸指標的值,不合適的使用這個值,上述陷阱的所有錯誤都有可能發生,遵守以下幾個約定
不要儲存p.get()的返回值
無論是儲存為裸指標還是shared_ptr都是錯誤的
儲存為裸指標不知什麼時候就會變成空懸指標
儲存為shared_ptr則產生了獨立指標
不要delete p.get()的返回值
會導致對一塊記憶體delete兩次的錯誤
如果用shared_ptr管理非new物件或是沒有析構函式的類時,應當為其傳遞合適的刪除器
unique ptr的使用和陷阱
與shared ptr不同,unique ptr沒有定義類似make shared的操作,因此只可以使用new來分配記憶體,並且由於unique ptr不可拷貝和賦值,初始化unique ptr必須使用直接初始化的方式。unique ptr up1 new int okay,直接初始化 unique...
unique ptr的使用和陷阱
與shared ptr不同,unique ptr沒有定義類似make shared的操作,因此只可以使用new來分配記憶體,並且由於unique ptr不可拷貝和賦值,初始化unique ptr必須使用直接初始化的方式。unique ptrup1 new int okay,直接初始化 unique ...
C 11智慧型指標Shared ptr陷阱
1.不要把乙個原生指標給多個shared ptr管理 int ptr new int shared ptr p1 ptr shared ptr p2 ptr logic error ptr物件被刪除了2次2.不要把this指標給shared ptr class test private shared...