網站首頁 編程語言 正文
前言
本章主要介紹一些C/C++中智能指針的實現原理以及如何使用
一、什么是智能指針
C/C++中,指針是一個非常重要的概念,其強大但也麻煩
麻煩之處就在于一旦你申請了內存,那就必須要手動去釋放內容,否則就會造成內存泄漏
當然了,在代碼量少的情況下你可能會不以為意,因為這點內存即使泄露了也根本看不出來,而且一旦程序執行結束,所有內存都會被系統釋放
但如果一旦寫比較大點的項目,內存管理就顯得很重要了,比如QQ,微信等等,一般都是一直掛著的
如果掛幾個小時就把電腦內存耗干凈了,瞬間電腦變卡,誰還用啊
所以智能指針的作用就是防止我們麻痹大意忘記釋放內存,幫助我們管理內存的
當然也有多次釋放一個指針,導致程序崩潰的問題也能就此解決
二、使用方法
雖然智能指針聽著很高級,但使用起來并不算復雜,熟悉之后,其實和普通指針差別不大。但會更加好用
自C++11之后,智能指針共有三個:shared_ptr、unique_ptr、weak_ptr
1.shared_ptr
看名字就知道,它是可以分享的指針,其使用方法很簡單:
比如這里有一個類:
class User {
public:
User() {
cout << "這是構造函數" << endl;
}
~User()
{
cout << "這是析構函數" << endl;
}
void TestFun() {
cout << "這是一個測試函數" << endl;
}
};
然后使用共享智能指針:
#include<iostream>
using namespace std;
//上面的那個類可以放在這里
int main() {
shared_ptr<User> p(new User());
shared_ptr<User> p1 = p;
shared_ptr<User> p2 = p;
p->TestFun(); //調用函數的方式和指針一樣
cout << p.use_count() << endl; //輸出共享個數
}
即:通過模板參數,傳入要構造的指針類型,然后在初始化的時候,就可以直接new一個對象即可
因為是共享的,所以它還能互相賦值,并可以用函數use_count返回當前共享的個數
其使用方法,如調用類的函數和屬性之類的,就和普通的指針一樣,用->進行調用即可,但是卻不需要我們去親自清理內存了!
看,現在我們并沒有清理內存,但這個類的析構函數卻被調用了!這就說明內存已經被正常釋放了
這就是智能指針的好處!
但智能指針寫著有點麻煩,每次聲明其類型都有一長串,所以一般我們會對指針進行重定義,達到簡化的目的:
typedef shared_ptr<User> SPUser;
int main() {
SPUser p(new User());
SPUser p1 = p;
SPUser p2 = p;
p->TestFun(); //調用函數的方式和指針一樣
cout << p.use_count() << endl; //輸出共享個數
}
2.unique_ptr
上面的共享指針的使用方法和普通指針區別并不大
但有時候,我們想要某個對象同時只能存在一份,即不允許像共享指針那樣,可以到處隨意賦值給別人
這時候就可以用unique_ptr,其使用方法如下:
typedef unique_ptr<User> UPUser; //重新定義一個名稱,便于使用
int main() {
UPUser p(new User);
//UPUser p1 = p; //錯誤,不能進行賦值
UPUser p2;
p2.swap(p); //但可以交換,即p2現在保存有變量,但p變為了空指針
if (p == nullptr) {
cout << "p為空指針" << endl;
}
p2->TestFun(); //正常調用
UPUser p3 = move(p2); //也可以用move函數移動
if (p2 == nullptr) { //此時p2就是空指針
cout << "p2為空指針" << endl;
}
p3->TestFun(); //p3則保存對象指針
}
可以看到,它的使用方法其實和共享指針是差不多的,唯一不同之處就是,它內部的指針值,同一時刻只能存在一份
即,你不能對它進行任何形式的復制,但是可以移動
3.weak_ptr
這個智能指針用的不太多,因為它本身并沒有太多實際的用途,而是主要作為shared_ptr的一個輔助類存在
比如有多少指向相同的 shared_ptr 指針、shared_ptr 指針指向的堆內存是否已經被釋放等等。
其使用方法如下:
typedef shared_ptr<User> SPUser;
typedef weak_ptr<User> WPUser;
int main() {
SPUser p(new User());
SPUser p1 = p;
SPUser p2 = p;
WPUser wp(p);
cout << wp.use_count() << endl; //查看這個共享指針使用次數
cout << wp.expired() << endl; //判斷這個指針是否為空,或者內存已經被釋放
}
原文鏈接:https://blog.csdn.net/weixin_50964512/article/details/128536406
相關推薦
- 2022-09-22 原型鏈及原型鏈的作用/構造函數,原型對象,實例對象的三角關系
- 2022-04-30 C#實現鼠標消息捕獲_C#教程
- 2022-11-25 React之echarts-for-react源碼解讀_React
- 2022-08-25 C語言詳細分析結構體的內存對齊規則_C 語言
- 2022-09-05 Hbase之查看RowKey所在Region
- 2022-01-11 我不會ES6-數據類型轉換-一個對象變為對象數組 Object.keys(obj)
- 2023-05-16 python實現動態規劃算法的示例代碼_python
- 2022-06-17 Ruby序列化和持久化存儲(Marshal、Pstore)操作方法詳解_Golang
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支