C++基礎之智能指針

一、概念

堆內存對象需要手動使用delete銷毀如果沒有使用delete銷毀就會造成內存泄漏

所以C++在ISO98標準引入了智能指針概念ISO11趨于完善

使用智能指針可以堆內存對象具有棧內存對象特點原理需要手動回收內內存對象套上一個棧內存的模板類對象即可

使用智能指針需要引入頭文件#include<memory>

C++四種智能指針

●?auto_ptr自動指針)C++ISO98 ,已廢棄)

●?unique_ptr唯一指針)C++ISO11)

●?shared_ptr共享指針C++ISO11)

●?weak_ptr虛指針)C++ISO11)

二、auto_ptr?

#include <iostream>
#include <memory>
using namespace std;
class Test
{
private:string s;
public:Test(string s):s(s){cout<<s<<"構造函數"<<endl;}~Test(){cout<<s<<"析構函數"<<endl;}void show(){cout<<s<<"對象執行"<<endl;}
};
int main()
{{//創建一個Test對象,t1指針指向對象Test *t1=new Test("A");//將對象t1交給ap1管理auto_ptr<Test>ap1(t1);//訪問對象的成員函數ap1.get()->show();  //ap1.get() <=等價=> t1//釋放智能指針ap1對對象t1的管理權,但不銷毀對象
//    ap1.release();//釋放智能指針ap1對對象t1的管理權,且銷毀對象
//    ap1.reset();//創建新的對象t2,銷毀原t1對象,并將ap1管理的對象換為t2Test *t2=new Test("B");ap1.reset(t2);//    //以上兩句代碼可簡寫為
//    ap1.reset(new Test("B"));ap1.get()->show();cout<<"局部代碼塊執行結束"<<endl;}cout<<"程序運行結束"<<endl;return 0;
}/*
A構造函數
A對象執行
B構造函數
A析構函數
B對象執行
局部代碼塊執行結束
B析構函數
程序運行結束
*/

由于成員變量存在指針類型,其拷貝構造函數和賦值運算符重載函數的使用會出現問題,與淺拷貝不同,auto_ptr的復制語義(拷貝構造函數、賦值運算符重載函數)會導致智能指針對對象控制權的轉移(非程序員本意),這也是他被廢棄的原因

#include <iostream>
#include <memory>
using namespace std;
class Test
{
private:string s;
public:Test(string s):s(s){cout<<s<<"構造函數"<<endl;}~Test(){cout<<s<<"析構函數"<<endl;}void show(){cout<<s<<"對象執行"<<endl;}
};
int main()
{{//創建一個Test對象,t1指針指向對象Test *t1=new Test("A");//將對象t1交給ap1管理auto_ptr<Test>ap1(t1);cout<<ap1.get()<<endl;//顯示調用拷貝構造函數auto_ptr<Test>ap2(ap1);//對t1的管理權從ap1到了ap2cout<<ap1.get()<<" "<<ap2.get()<<endl;//隱式調用拷貝構造函數auto_ptr<Test>ap3=ap2;//對t1的管理權從ap2到了ap3cout<<ap1.get()<<" "<<ap2.get()<<" "<<ap3.get()<<endl;//使用賦值運算符auto_ptr<Test>ap4;ap4=ap3; //對t1的管理權從ap3到了ap4cout<<ap1.get()<<" "<<ap2.get()<<" "<<ap3.get()<<" "<<ap4.get()<<endl;cout<<"局部代碼塊執行結束"<<endl;}cout<<"程序運行結束"<<endl;return 0;
}/*
A構造函數
0x1162670
0 0x1162670
0 0 0x1162670
0 0 0 0x1162670
局部代碼塊執行結束
A析構函數
程序運行結束
*/

三、unique_ptr?

作為auto_ptr的改進,unique_ptr對其他持有資源對象具有唯一控制權不可以通過常規復制語法轉移或者拷貝資源對象控制

?

?

#include <iostream>
#include <memory>
using namespace std;
class Test
{
private:string s;
public:Test(string s):s(s){cout<<s<<"構造函數"<<endl;}~Test(){cout<<s<<"析構函數"<<endl;}void show(){cout<<s<<"對象執行"<<endl;}
};
int main()
{{//創建一個Test對象,t1指針指向對象Test *t1=new Test("A");//將對象t1交給up1管理unique_ptr<Test>up1(t1);cout<<up1.get()<<endl;//顯示調用拷貝構造函數unique_ptr<Test>up2(move(up1));cout<<up1.get()<<" "<<up2.get()<<endl;//隱式調用拷貝構造函數unique_ptr<Test>up3=move(up2);cout<<up1.get()<<" "<<up2.get()<<" "<<up3.get()<<endl;//使用賦值運算符unique_ptr<Test>up4;up4=move(up3);cout<<up1.get()<<" "<<up2.get()<<" "<<up3.get()<<" "<<up4.get()<<endl;cout<<"局部代碼塊執行結束"<<endl;}cout<<"程序運行結束"<<endl;return 0;
}/*
A構造函數
0xed2670
0 0xed2670
0 0 0xed2670
0 0 0 0xed2670
局部代碼塊執行結束
A析構函數
程序運行結束
*/

?四、shared_ptr

?

每次多一個shared_ptr對資源進行管理引用計數+1每個指向該對象shared_ptr對象銷毀時引用計數-1最后一個shared_ptr對象銷毀時計數清零資源對象銷毀
(即對于所有管理某對象A的 shared_ptr,這些 shared_ptr共享的資源有:引用計數、對象資源)?
#include <iostream>
#include <memory>
using namespace std;
class Test
{
private:string s;
public:Test(string s):s(s){cout<<s<<"構造函數"<<endl;}~Test(){cout<<s<<"析構函數"<<endl;}void show(){cout<<s<<"對象執行"<<endl;}
};
int main()
{shared_ptr<Test>sp3;{shared_ptr<Test>sp1=make_shared<Test>("A");cout<<"引用計數:"<<sp1.use_count()<<endl;cout<<"-------------"<<endl;shared_ptr<Test>sp2(sp1);cout<<"引用計數:"<<sp2.use_count()<<endl;cout<<"引用計數:"<<sp1.use_count()<<endl;cout<<"-------------"<<endl;sp3=sp2;cout<<"引用計數:"<<sp3.use_count()<<endl;cout<<"局部代碼塊執行結束"<<endl;}//此時sp1、sp2都已銷毀,所以引用計數減2cout<<"引用計數:"<<sp3.use_count()<<endl;cout<<"程序運行結束"<<endl;return 0;
}/*
A構造函數
引用計數:1
-------------
引用計數:2
引用計數:2
-------------
引用計數:3
局部代碼塊執行結束
引用計數:1
程序運行結束
A析構函數*/

?五、weak_ptr

weak_ptr一個不控制資源對象智能指針不會影響資源引用計數主要目的協助shared_ptr工作

通過weak_ptr構造函數參數傳入一個持有資源對象shared_ptr或者weak_ptr對象即可創建weak_ptr與資源對象呈弱相關性,因此不支持get等函數直接操作資源對象.

建議weak_ptr調用lock函數之前,先檢測引用計數是否大于0,或使用expired()函數檢測是否可轉換為shared_ptr.

  • 因為不會增加引用計數,所以作為觀察者,觀察對象是否被釋放
  • 若shared_ptr失效,weak_ptr可以通過lock函數“轉正”
  • shared_ptr在特殊場景下也會造成內存泄漏(循環引用導致智能指針內存泄漏的問題),可以使用weak_ptr來解決
#include <iostream>
#include <memory>
using namespace std;
class Test
{
private:string s;
public:Test(string s):s(s){cout<<s<<"構造函數"<<endl;}~Test(){cout<<s<<"析構函數"<<endl;}void show(){cout<<s<<"對象執行"<<endl;}
};
int main()
{weak_ptr<Test>wp3;{shared_ptr<Test>sp1=make_shared<Test>("A");weak_ptr<Test>wp1=sp1;weak_ptr<Test>wp2(wp1);cout<<sp1.use_count()<<endl;cout<<wp1.use_count()<<endl;cout<<wp2.use_count()<<endl;cout<<"-----------"<<endl;//weak_ptr可以通過lock函數“轉正”shared_ptr<Test>sp2=wp1.lock();wp3=wp2;cout<<wp3.use_count()<<endl;cout<<"局部代碼塊執行結束"<<endl;}//判斷能否轉正cout<<wp3.use_count()<<endl;if(wp3.expired()){cout<<"weak_ptr無法轉正"<<endl;}cout<<"程序運行結束"<<endl;return 0;
}/*
A構造函數
1
1
1
-----------
2
局部代碼塊執行結束
A析構函數
0
weak_ptr無法轉正
程序運行結束*/

?六、其他

1.nullptr

在C++11使用nullptr代替NULL作為空指針表示方式C++可以用作空指針常量表示指針指向任何有效內存地址

?2.類型推導

2.1? auto

使用auto關鍵字可以推導類型C++11引入

#include <iostream>
#include <memory>
using namespace std;int main()
{auto i1=10;//typeof(i1)-->整型auto i2=1.5;//typeof(i2)-->浮點型auto i3=new auto(10); //typeof(i3)-->int *//int* i3=new int(10);cout<<*i3<<" "<<i3<<endl;auto i4='a';//typeof(i4)-->charreturn 0;
}

2.2?decltypt

decltypt可以推導表達式類型需要注意decltypt只會分析表達式類型不會具體計算表達式

3.初始化列表

#include <iostream>
#include <array>
#include <vector>using namespace std;class Student
{
private:string name;int age;
public:Student(string name,int age):name(name),age(age){}void show(){cout << name << " " << age << endl;}
};int main()
{Student s = {"張勝男",18}; // 列表初始化s.show();array<int,5>arr1 = {1,3,4,5,6};vector<int> vec1 ={1,2,3};int arr2[] = {2,3,45,6};int a{};cout << a << endl;  // 0return 0;
}

4.面試題

【面試題】C++11學過那些特性
  • auto(類型推導)
  • 智能指針(unique_ptr、?shared_ptr、weak_ptr)
  • 初始化列表
  • for-each
  • 類型轉換函數
  • 繼承構造
  • array
  • override

?5.? 進制輸出

C++11可以對整數進行不同進制輸出
#include <iostream>using namespace std;int main()
{// 為了區分不同進制,可以增加進制顯式的功能,此功能設定持久cout << showbase;cout << dec << 1234 << endl;    // 1234cout << oct << 1234 << endl;    // 02322// 輸出進制是持久的cout << 9 << endl;  // 011cout << hex << 256 << endl; // 0x100// 取消進制顯式的功能cout << noshowbase;cout << 16 << endl; // 10return 0;
}

6.??設定輸出域寬度

可以使用setw()制定一個整數或者一個字符串輸出占用與寬度

●?設定寬度小于數據本身時仍然顯示為數據本身寬度

●?設定域寬度大于數據本身顯式未設定寬度

?

#include <iostream>
#include <iomanip>using namespace std;int main()
{// 仍然會按照實際的寬度輸出cout << setw(5) << 123456 << setw(5) << 123456 << endl;cout << setw(10) << 123456 << setw(10) << 123456 << endl;// 域寬度 只能作用于下一行cout << setw(10);cout << 123456 << endl;cout << 123456 << endl;return 0;
}

拓展學習

C++如何實現多線程多進程案例:線程池)

文件處理案例:日志系統)

客戶端服務器高并發??

Lambda表達式

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/88399.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/88399.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/88399.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

python3虛擬機線程切換過程

python實現了自己的多線程&#xff0c;為了保證線程安全&#xff0c;引入了全局解釋器鎖GIL&#xff0c;只有拿到GIL的線程才能執行&#xff0c;所以在python中同一時刻只能有一個線程在運行&#xff0c;python多線程無法發揮多核處理器的威力&#xff0c;《python源碼剖析》中…

PYTHON從入門到實踐5-列表操作

# 【1】列表是可變的&#xff0c;可以修改、追加、刪除 import randomclass Friend(object):def __init__(self, name, age):self.name nameself.age ageif __name__ __main__:friendList []for i in range(0, 9):randomNumber random.randint(0, 100)friend Friend(f&qu…

【linux】network服務啟動網卡流程

目錄 1、介紹2、ifup流程【1】與NetworkManager兼容【2】ifup-eth設置ip【3】ifup-routes設置路由 1、介紹 network服務的核心由/etc/sysconfig/network-scripts/下一堆腳本配置來生效&#xff0c;其中啟動網卡就是通過ifup腳本來實現的&#xff0c;下面就講一下ifup如何恢復i…

如何防止自己的電腦被控制?開啟二次驗證保護教程

遠程操作什么最重要&#xff1f;安全&#xff0c;安全&#xff0c;和安全&#xff01;答案永遠是安全&#xff01;那么究竟如何能讓遠程連接安全性更上一層臺階吶&#xff1f;又是哪家遠控安全策略方面最給力吶&#xff1f;這可不是王婆賣瓜&#xff0c;自賣自夸&#xff0c;確…

微信小程序節點相關總結

微信小程序節點事件總結 bindtap、catchtap、bindclick的區別&#xff1f;bindclick 和 bindtap 的區別在于&#xff1a; e.target和e.currentTargete.typee.timeStamp觸摸事件屬性&#xff08;針對觸摸類事件&#xff09;坐標信息事件綁定數據冒泡與捕獲相關其他特殊屬性**常見…

XSD是什么,與XML關系

XSD&#xff08;XML Schema Definition&#xff09;是用于描述XML文檔結構和內容的一種規范。它定義了XML文檔中元素、屬性、數據類型、數據格式以及它們之間的關系和約束。XSD是W3C&#xff08;萬維網聯盟&#xff09;推薦的標準之一&#xff0c;它比早期的DTD&#xff08;Doc…

Ubuntu服務器中MySQL如何進行主從復制

一、MySQL 主從復制基本原理 MySQL 主從復制是指&#xff1a;一臺數據庫服務器負責寫入操作&#xff0c;并將數據變更以二進制日志形式記錄下來;一臺或多臺從庫通過讀取主庫的二進制日志&#xff0c;實時或半實時地將主庫的寫入操作同步到自身數據庫&#xff0c;實現數據一致性…

Android圖形系統框架解析

前言 Android圖形系統對于開發者來說可能會比較難以理解&#xff0c;因為涉及的東西可能會計較多&#xff0c;比如Android自己的圖形系統。OpenGL&#xff0c;視頻編解碼器&#xff0c;SurfaceFlinger&#xff0c;FrameBuffer等等。下面我們結合官方文檔&#xff0c;介紹一下圖…

AI智能巡檢系統給烘焙店開的「減損藥方」 InfiSight智睿視界

01 食材浪費&#xff1a;甜蜜產業的苦澀成本 后廚操作臺上&#xff0c;剛過最佳賞味期的可頌成批倒入垃圾桶——這是烘焙店最隱秘的痛。現烤現售模式雖保障新鮮度&#xff0c;卻讓原料管理淪為盲區&#xff1a; 銷售數據≠生產指南&#xff1a;總部無法感知門店實時庫存 …

工具 | vscode 發出聲音,如何關閉

設置->搜 accessibility -> Accessibility Support -> 自動 改為 off 設置->搜 volume -> 0 設置->搜 sound -> 輔助功能信號 -> sound的 自動 改為 off 參考&#xff1a; How to turn off (or on) sounds from Visual Studio Code? - Stack Ove…

Hyperf 數據庫事務指南(PHP 框架)

Hyperf 數據庫事務指南&#xff08;PHP 框架&#xff09; 1. ?? 數據庫配置 1.1 配置文件 MySQL 配置位于 config/database.php&#xff0c;通常通過環境變量&#xff08;.env&#xff09;管理敏感信息&#xff1a; <?phpdeclare(strict_types 1); /*** This file i…

動態ds-vnp之normal和shortcut兩種方式配置案例

normal方式配置 hub配置 dhcp enable interface GigabitEthernet0/0/0 ip address 3.3.3.3 255.255.255.0 interface GigabitEthernet0/0/1 ip address 192.168.3.254 255.255.255.0 dhcp select interface interface Tunnel0/0/0 ip address 10.1.1.3 255.255.255.0 tunnel…

ubuntu20.04調試livox aiva驅動獲取激光雷達數據

實驗環境ubuntu20.04 平臺包括本地x86平臺和jetson orin平臺都測試ok 參考 ubuntu20.04上獲取Livox Avia雷達點云數據 1.下載相關資料 下載包括&#xff1a;Livox Avia 用戶手冊中文.pdf、Livox_Viewer_For_Linux_Ubuntu16.04_x64_0.10.0&#xff08;用于顯示激光雷達數據&am…

VS2022 C#【自動化文件上傳】AutoFileUpload 新需求 V13

這里寫自定義目錄標題 需求分析實現方法原來&#xff08;需要修改的位置&#xff09;替換為如下代碼&#xff08;添加三行數據&#xff09; 需求 現在已有程序&#xff1a;AutoFileUpload 存儲excel表中時間列的第一列的列名到數據庫中 分析 user只是想存儲列名到數據表列去…

技術QA | ADC/DAC芯片測試研討會筆記請查收!

6月19日&#xff0c;《ADC/DAC芯片測試前沿&#xff1a;德思特ATX系統高效方案與實戰攻略》線上研討會圓滿結束。感謝大家的觀看與支持&#xff01; 在直播間收到一些觀眾的技術問題&#xff0c;我們匯總了熱點問題并請講師詳細解答&#xff0c;在此整理分享給大家&#xff0c…

區塊鏈技術未來的發展趨勢

以下是區塊鏈技術未來的一些發展趨勢&#xff1a; 技術層面 - 性能提升&#xff1a;分片技術會不斷成熟和完善&#xff0c;將區塊鏈網絡劃分為多個分片&#xff0c;每個分片獨立處理交易&#xff0c;以提高交易吞吐量和網絡可擴展性。同時&#xff0c;共識機制也會持續創新&a…

電商領域企業級應用后端開發 (Java) 就業前景深度分析報告 (2025-2030)

目錄 一、行業概述與發展趨勢 1.1 電商行業發展現狀與趨勢 1.2 電商技術架構演進與趨勢 二、電商領域 Java 開發崗位需求分析 2.1 崗位數量變化趨勢 2.2 崗位地域分布特點 2.3 崗位層級與職責變化 三、電商領域 Java 開發人才競爭分析 3.1 人才供需狀況 3.2 人才競爭核…

DVWA Brute Force漏洞深度分析與利用指南

DVWA簡介 DVWA&#xff08;Damn Vulnerable Web Application&#xff09;是一個基于PHP/MySQL的脆弱性Web應用平臺&#xff0c;專為安全專業人員設計&#xff0c;用于測試技能和工具。它包含十大安全模塊&#xff0c;其中Brute Force&#xff08;暴力破解&#xff09;是最基礎…

【Android】Activity 的生命周期和啟動模式

文章目錄 Activity 的生命周期和啟動模式1. 任務和返回棧2. Activity 的四種狀態2.1 運行狀態2.2 暫停狀態2.3 停止狀態2.4 銷毀狀態 3. Activity的生命周期3.1 生命周期回調方法3.2 演示 Activity 的生命周期 4. Activity的啟動模式4.1 standard&#xff08;標準模式&#xff…

八大架構憲法 - 技術使用指導說明文檔

我們定義了八部宏偉的“架構憲法”,這份 《八大架構憲法技術使用指導說明文檔》,將作為交付給人類架構師和高級AI代理的 “戰術手冊”。 核心目標是:將每一部憲法的抽象哲學,轉化為在項目不同階段中、具體的、可操作的技術決策指南。回答一個關鍵問題:“在選擇了某一部憲…