目錄
- 往期文章
- 智能指針本身的方法
- 對于unique_ptr
- 對于shared_ptr
- 對于weak_ptr
- 使用建議
- 1、使用工廠函數而非new構造對象
- 2、在類內部調用其他類的方法
- 3、在某類內部將當前對象指針共享給其他對象
- 4、 智能指針只能管理堆對象,不能管理棧上對象
- 5、不能將this指針直接托管給智能指針
往期文章
C++智能指針使用指南 part1:基本使用
智能指針本身的方法
智能指針有一個通用的規則,就是->
表示用于調用指針原有的方法,而.
則表示調用智能指針本身的方法。
對于unique_ptr
#include <iostream>
#include <vector>
#include <memory>
#include <assert.h>
using namespace std;
class A {
public:void do_something();
};
// 智能指針有一個通用的規則,就是`->`表示用于調用指針原有的方法,而`.`則表示調用智能指針本身的方法.
// 對于unique_ptr有下面幾種本身方法
// get 獲取智能指針保存的原生指針
// bool 判斷該智能指針是否擁有指針
// release 釋放所管理指針的所有權,返回原生指針,但是不銷毀原生指針
// reset 釋放并銷毀原生指針。如果參數為一個新指針,將管理這個新指針
int main() {std::unique_ptr<A> a(new A());A* origin_a = a.get();if (a) {printf("a仍然擁有指針");}std::unique_ptr<A> a2(a.release()); // 轉移擁有權a2.reset(new A()); // 釋放并銷毀原有對象,持有一個新對象a2.reset(); // 釋放并銷毀原有對象,等同于 a2 == nullptrassert(a2 == nullptr);return 0;
}
對于shared_ptr
// 對于shared_ptr有下面幾種本身方法
// get 獲取智能指針保存的原生指針
// bool 判斷該智能指針是否擁有指針
// reset 釋放并銷毀原生指針。如果參數為一個新指針,將管理這個新指針
// unique 如果引用計數為1返回true,否則返回false
// use_count 返回引用計數大小
對于weak_ptr
weak_ptr可以通過一個shared_ptr創建
// 智能指針有一個通用的規則,就是`->`表示用于調用指針原有的方法,而`.`則表示調用智能指針本身的方法.
// expired 判斷所指向的原生指針是否被釋放,如果釋放了返回true,否則返回false
// use_count 返回原生指針的引用計數
// lock 返回shared_ptr;如果原生指針沒有被釋放,則返回一個非空的shared_ptr,否則返回一個空的shared_ptr
// reset 將本身置空
int main() {std::shared_ptr<A> a(new A());std::weak_ptr<A> weak_a = a; // 不增加引用計數}
使用建議
1、使用工廠函數而非new構造對象
在上面的代碼中需要注意,我們使用std::make_shared
代替new
的方式創建shared_ptr
。
因為使用new
的方式創建shared_ptr
會導致出現兩次內存申請,而std::make_shared
在內部實現時只會申請一個內存。
2、在類內部調用其他類的方法
不可以在A內部定義B、C的shared_ptr,而是應該使用weak_ptr
class A {
private:std::weak_ptr<B> b_;std::weak_ptr<C> c_;
public:void do_something();void set_b_c(const std::shared_ptr<B>& b, const std::shared_ptr<C>& c) {b_ = b;c_ = c;}
};
3、在某類內部將當前對象指針共享給其他對象
#include <iostream>
#include <vector>
#include <memory>
using namespace std;
class A;class D {
private:std::shared_ptr<A> a_;
public:D(std::shared_ptr<A>& a): a_(a) {}
};class A : public std::enable_shared_from_this<A>{
public:void new_D(){// 錯誤方式,用this指針重新構造shared_ptr,將導致二次釋放當前對象,重新創建的shared_ptr與當前對象的shared_ptr沒有關系,沒有增加當前對象的引用計數// 關于這個問題,可以詳細地看一下這篇博客:https://www.cnblogs.com/jo3yzhu/p/11358400.html
// std::shared_ptr<A> this_shared_ptr1(this);
// std::unique_ptr<D> d1(new D(this_shared_ptr1));// 正確方式 對象繼承了enable_shared_from_this后,可以通過shared_from_this()獲取當前對象的shared_ptr指針。std::shared_ptr<A> this_shared_ptr2 = shared_from_this();std::unique_ptr<D> d2(new D(this_shared_ptr2));}
};int main() {std::shared_ptr<A> a(new A());a->new_D();
}
4、 智能指針只能管理堆對象,不能管理棧上對象
棧上對象本身在出棧的時候就會被自動銷毀,如果將其指針交給智能指針,會造成對象的二次銷毀。
void function() {int tmp = 0;std::unique_ptr<int> a(tmp);
}
5、不能將this指針直接托管給智能指針
如果對一個類初始化為智能指針,那么在類內部函數用this指針重新構造shared_ptr,不會增加引用計數,會導致當前對象的二次釋放。
class A {
public:void function() {// 錯誤方式std::shared_ptr<A> this_shared_ptr(this);}
};
std::shared_ptr<A> e = std::make_shared<E>();