最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++智能指針的使用

 更新時(shí)間:2025年02月13日 08:30:43   作者:英雄不問(wèn)出處~  
本文主要介紹了C++智能指針的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

智能指針的使用場(chǎng)景

1. 下面的程序中,new了以后,我們也delete了,但是因?yàn)閽伄惓?dǎo)致后面的delete沒(méi)有得到執(zhí)行,所以就內(nèi)存泄漏了,所以我們需要new以后捕獲異常,捕獲到異常后delete內(nèi)存,再把異常拋出。
2.但是因?yàn)閚ew本身也可能拋異常,連續(xù)的兩個(gè)new和下面的Divide都可能會(huì)拋異常,讓我們處理起來(lái)很麻煩。智能指針?lè)诺竭@樣的場(chǎng)景里面就讓問(wèn)題簡(jiǎn)單多了。

double Divide(int a, int b)
{
	// 當(dāng)b == 0時(shí)拋出異常
	if (b == 0)
	{
		throw "Divide by zero condition!";
	}
	else
	{
		return (double)a / (double)b;
	}
}

void Func()
{
	// 這?可以看到如果發(fā)?除0錯(cuò)誤拋出異常,另外下?的array和array2沒(méi)有得到釋放。
	// 所以這?捕獲異常后并不處理異常,異常還是交給外?處理,這?捕獲了再重新拋出去。
	// 但是如果array2new的時(shí)候拋異常呢,就還需要套?層捕獲釋放邏輯,這?更好解決?案
	// 是智能指針,否則代碼太戳了
	int* array1 = new int[10];
	int* array2 = new int[10];// 拋異常呢
	// 連續(xù)的兩個(gè)new
	// 如果第一個(gè)new拋異常可以捕獲
	// 如果第二個(gè)new拋異常,可以解決delete第二個(gè)new
	// 但是第一個(gè)new沒(méi)有被delete
	// 這樣就需要再第二個(gè)new的地方捕獲異常,delete第一個(gè)new
	// 如果有很多個(gè)new呢,就太麻煩了,這里就需要智能指針了
	try
	{
		int len, time;
		cin >> len >> time;
		cout << Divide(len, time) << endl;
	}
	catch (...)
	{
		cout << "delete []" << array1 << endl;
		cout << "delete []" << array2 << endl;
		delete[] array1;
		delete[] array2;
		throw; // 異常重新拋出,捕獲到什么拋出什么
	}
	// ...
	cout << "delete []" << array1 << endl;
	delete[] array1;
	cout << "delete []" << array2 << endl;
	delete[] array2;
}

int main()
{
	try
	{
		Func();
	}
	catch (const char* errmsg)
	{
		cout << errmsg << endl;
	}
	catch (const exception& e)
	{
		cout << e.what() << endl;
	}
	catch (...)
	{
		cout << "未知異常" << endl;
	}

	return 0;
}

RAII和智能指針

1. RAII是獲取到資源立即初始化,它是一種管理資源的類的設(shè)計(jì)思想,本質(zhì)是一種利用對(duì)象生命周期來(lái)管理獲取到的動(dòng)態(tài)資源,避免資源泄漏,這里的資源可以是內(nèi)存、文件指針、網(wǎng)絡(luò)連接、互斥鎖等等。RAII在獲取資源時(shí)把資源委托給一個(gè)對(duì)象,接著控制對(duì)資源的訪問(wèn),資源在對(duì)象的生命周期內(nèi)始終保持有效,最后在對(duì)象析構(gòu)的時(shí)候釋放資源,這樣保障了資源的正常釋放,避免資源泄漏問(wèn)題。

2. RAII像指針一樣

在對(duì)象銷(xiāo)毀后會(huì)正常的釋放資源

template<class T>
class SmartPtr
{
public:
	// RAII
	SmartPtr(T* ptr)
		:_ptr(ptr)
	{}

	~SmartPtr()
	{
		cout << "delete[] " << _ptr << endl;
		delete[] _ptr;
	}

private:
	T* _ptr;
};

double Divide(int a, int b)
{
	// 當(dāng)b == 0時(shí)拋出異常
	if (b == 0)
	{
		throw "Divide by zero condition!";
	}
	else
	{
		return (double)a / (double)b;
	}
}

void Func()
{
	// 這?可以看到如果發(fā)?除0錯(cuò)誤拋出異常,另外下?的array和array2沒(méi)有得到釋放。
	// 所以這?捕獲異常后并不處理異常,異常還是交給外?處理,這?捕獲了再重新拋出去。
	// 但是如果array2new的時(shí)候拋異常呢,就還需要套?層捕獲釋放邏輯,這?更好解決?案
	// 是智能指針,否則代碼太戳了
	SmartPtr<int> p1 = new int[10];
	SmartPtr<int> p2 = new int[10];// 拋異常呢
	SmartPtr<int> p3 = new int[10];

	int len, time;
	cin >> len >> time;
	cout << Divide(len, time) << endl;
}

int main()
{
	try
	{
		Func();
	}
	catch (const char* errmsg)
	{
		cout << errmsg << endl;
	}
	catch (const exception& e)
	{
		cout << e.what() << endl;
	}
	catch (...)
	{
		cout << "未知異常" << endl;
	}

	return 0;
}

智能指針類除了滿足RAII的設(shè)計(jì)思路,還要方便資源的訪問(wèn),所以智能指針類還像迭代器類一樣重載 operator*/operator->/operator[] 等運(yùn)算符,方便訪問(wèn)資源。

template<class T>
class SmartPtr
{
public:
	// RAII
	SmartPtr(T* ptr)
		:_ptr(ptr)
	{}

	~SmartPtr()
	{
		cout << "delete[] " << _ptr << endl;
		delete[] _ptr;
	}

	// 重載運(yùn)算符,模擬指針的?為,?便訪問(wèn)資源
	T& operator*()
	{
		return *_ptr;
	}

	T* operator->()
	{
		return _ptr;
	}

	T& operator[](size_t i)
	{
		return _ptr[i];
	}

private:
	T* _ptr;
};

void Func()
{
   p1[1] = 50;
   p4->first = 1;
   p4->second = 2;
   cout << p1[1] << endl;
}

C++標(biāo)準(zhǔn)庫(kù)智能指針的使用

淺拷貝的問(wèn)題,共同管理同一塊資源,而深拷貝是兩個(gè)指針管理不同的資源了,現(xiàn)在要求兩個(gè)指針管理同一塊資源?

int main()
{
	// 需要p1和p2同時(shí)管理同一塊資源,淺拷貝
	// 析構(gòu)多次的問(wèn)題如何解決?
	SmartPtr<int> p1 = new int[10];
	SmartPtr<int> p2(p1);

	return 0;
}

1.C++標(biāo)準(zhǔn)庫(kù)中的智能指針都在< memory >這個(gè)頭文件下,智能指針有好幾種,除了weak_ptr他們都符合RAII和像指針一樣訪問(wèn)的行為,原理上而言主要是解決智能指針拷貝時(shí)的思路不同。
2. C++98的智能指針

auto_ptr是C++98時(shí)設(shè)計(jì)出來(lái)的智能指針,它的特點(diǎn)是拷貝時(shí)把被拷貝對(duì)象的資源的管理權(quán)轉(zhuǎn)移給拷貝對(duì)象,這是?個(gè)非常糟糕的設(shè)計(jì),因?yàn)樗麜?huì)把被拷貝對(duì)象懸空(相當(dāng)于被拷貝對(duì)象是空指針了),訪問(wèn)報(bào)錯(cuò)的問(wèn)題,C++11設(shè)計(jì)出新的智能指針后,強(qiáng)烈建議不要使用auto_ptr

struct Date
{
	int _year;
	int _month;
	int _day;

	Date(int year = 1, int month = 1, int day = 1)
		:_year(year)
		, _month(month)
		, _day(day)
	{}

	// 本身不需要析構(gòu),為了驗(yàn)證auto_ptr是否可以解決析構(gòu)兩次的問(wèn)題
	~Date()
	{
		cout << "~Date()" << endl;
	}
};

int main()
{
	// 拷?時(shí),管理權(quán)限轉(zhuǎn)移,被拷?對(duì)象ap1懸空
	auto_ptr<Date> ap1(new Date);

	auto_ptr<Date> ap2(ap1);
	// 空指針訪問(wèn),ap1對(duì)象已經(jīng)懸空
	// ap1->_year++;

	return 0;
}

C++11的智能指針

2、unique_ptr是唯一指針,他的特點(diǎn)是不支持拷貝,只支持移動(dòng)。如果不需要拷貝的場(chǎng)景就非常建議使用它。把拷貝構(gòu)造和拷貝賦值給(封)delete了

int main()
{
   unique_ptr<Date> up1(new Date);

   不支持拷貝
   // unique_ptr<Date> up2(up1);

   支持移動(dòng),移動(dòng)后up1也懸空了
   unique_ptr<Date> up3(move(up1));

   return 0;
}

3、shared_ptr共享指針,他的特點(diǎn)是支持拷貝,也支持移動(dòng)。如果需要拷貝的場(chǎng)景就需要使用他了。底層是用引用計(jì)數(shù)的方式實(shí)現(xiàn)的。

int main()
{
   shared_ptr<Date> p1(new Date);
   shared_ptr<Date> p2(p1);
   shared_ptr<Date> p3(p1);
   
   cout << p1.use_count() << endl;// 3
   p1->_day++;
   cout << p1->_day << endl; // 2
   cout << p2->_day << endl; // 2
   cout << p3->_day << endl; // 2
   
   return 0;
}

4、weak_ptr弱(輔助解決shared_ptr的一個(gè)問(wèn)題)指針,它不同于上面的指針,它不支持RAII,也就意味著不能用它直接管理資源,weak_ptr的產(chǎn)生本質(zhì)是要解決shared_ptr的一個(gè)循環(huán)引用導(dǎo)致內(nèi)存泄漏的問(wèn)題。

到此這篇關(guān)于C++智能指針的使用的文章就介紹到這了,更多相關(guān)C++智能指針內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

  • C++算術(shù)運(yùn)算符與類型轉(zhuǎn)換

    C++算術(shù)運(yùn)算符與類型轉(zhuǎn)換

    這篇文章主要介紹了C++算術(shù)運(yùn)算符與類型轉(zhuǎn)換,C++當(dāng)中提供5種基礎(chǔ)的算術(shù)運(yùn)算符,分別是加法、減法、乘法、除法和取模。下main我們就一起來(lái)看看下面文章得具體舉例與說(shuō)明,需要的朋友可以參考一下,希望對(duì)你有所幫助
    2021-11-11
  • C語(yǔ)言實(shí)現(xiàn)掃雷小游戲(擴(kuò)展版可選擇游戲難度)

    C語(yǔ)言實(shí)現(xiàn)掃雷小游戲(擴(kuò)展版可選擇游戲難度)

    游戲目標(biāo)是找出所有沒(méi)有地雷的方格,完成游戲;要是按了有地雷的方格,游戲失??;玩家可標(biāo)記雷的位置,游戲以完成時(shí)間來(lái)評(píng)高低,并且用戶可以選擇游戲難度
    2019-10-10
  • C語(yǔ)言實(shí)現(xiàn)套接字操作的示例代碼

    C語(yǔ)言實(shí)現(xiàn)套接字操作的示例代碼

    在C語(yǔ)言中,套接字(Socket)是一種進(jìn)行網(wǎng)絡(luò)通信的接口,這篇文章就來(lái)和大家介紹一下C語(yǔ)言中是如何進(jìn)行套接字操作的,需要的可以參考一下
    2023-06-06
  • C語(yǔ)言編程中生成隨機(jī)數(shù)的入門(mén)教程

    C語(yǔ)言編程中生成隨機(jī)數(shù)的入門(mén)教程

    這篇文章主要介紹了C語(yǔ)言編程中生成隨機(jī)數(shù)的入門(mén)教程,包括利用rand()函數(shù)來(lái)編寫(xiě)隨機(jī)數(shù)生成器的示例,要的朋友可以參考下
    2015-12-12
  • C++?Qt開(kāi)發(fā)之使用QUdpSocket實(shí)現(xiàn)組播通信

    C++?Qt開(kāi)發(fā)之使用QUdpSocket實(shí)現(xiàn)組播通信

    Qt?是一個(gè)跨平臺(tái)C++圖形界面開(kāi)發(fā)庫(kù),利用Qt可以快速開(kāi)發(fā)跨平臺(tái)窗體應(yīng)用程序,本文將重點(diǎn)介紹如何運(yùn)用QUdpSocket組件實(shí)現(xiàn)基于UDP的組播通信,感興趣的可以了解下
    2024-03-03
  • C語(yǔ)言零基礎(chǔ)入門(mén)(1)

    C語(yǔ)言零基礎(chǔ)入門(mén)(1)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言零基礎(chǔ)入門(mén)的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-03-03
  • C語(yǔ)言 socketpair用法案例講解

    C語(yǔ)言 socketpair用法案例講解

    這篇文章主要介紹了C語(yǔ)言 socketpair用法案例講解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • vscode+leetcode環(huán)境配置方法

    vscode+leetcode環(huán)境配置方法

    這篇文章主要介紹了vscode+leetcode環(huán)境配置,本文通過(guò)實(shí)例圖文相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-03-03
  • C語(yǔ)言中改變目錄的相關(guān)操作函數(shù)詳解

    C語(yǔ)言中改變目錄的相關(guān)操作函數(shù)詳解

    這篇文章主要介紹了C語(yǔ)言中改變目錄的相關(guān)操作函數(shù)詳解,分別是fchdir()函數(shù)和rewinddir()函數(shù)的使用方法,需要的朋友可以參考下
    2015-09-09
  • C++與Lua交互內(nèi)存分配詳解

    C++與Lua交互內(nèi)存分配詳解

    C/C++ 與 Lua 的交互是通過(guò) lua_State 這一句柄進(jìn)行交互,我們常規(guī)的創(chuàng)建都是通過(guò) luaL_newstate 這一輔助函數(shù),這篇文章主要給大家詳細(xì)介紹了C++與Lua交互內(nèi)存分配,文中有相關(guān)的代碼示例供大家參考,需要的朋友可以參考下
    2023-11-11

最新評(píng)論

静海县| 普定县| 林周县| 融水| 三门县| 咸阳市| 满洲里市| 石城县| 历史| 昭苏县| 连城县| 全椒县| 孝感市| 义乌市| 商洛市| 团风县| 武夷山市| 泗洪县| 邢台市| 淮北市| 洛隆县| 莱西市| 襄樊市| 洞口县| 鲁甸县| 县级市| 尉犁县| 金寨县| 奉新县| 通化市| 札达县| 吴桥县| 黄浦区| 铜陵市| 吴川市| 女性| 东城区| 高清| 岚皋县| 民和| 阳新县|