亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C++智能指針的使用

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

智能指針的使用場景

1. 下面的程序中,new了以后,我們也delete了,但是因為拋異常導致后面的delete沒有得到執(zhí)行,所以就內(nèi)存泄漏了,所以我們需要new以后捕獲異常,捕獲到異常后delete內(nèi)存,再把異常拋出。
2.但是因為new本身也可能拋異常,連續(xù)的兩個new和下面的Divide都可能會拋異常,讓我們處理起來很麻煩。智能指針放到這樣的場景里面就讓問題簡單多了。

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

void Func()
{
	// 這?可以看到如果發(fā)?除0錯誤拋出異常,另外下?的array和array2沒有得到釋放。
	// 所以這?捕獲異常后并不處理異常,異常還是交給外?處理,這?捕獲了再重新拋出去。
	// 但是如果array2new的時候拋異常呢,就還需要套?層捕獲釋放邏輯,這?更好解決?案
	// 是智能指針,否則代碼太戳了
	int* array1 = new int[10];
	int* array2 = new int[10];// 拋異常呢
	// 連續(xù)的兩個new
	// 如果第一個new拋異??梢圆东@
	// 如果第二個new拋異常,可以解決delete第二個new
	// 但是第一個new沒有被delete
	// 這樣就需要再第二個new的地方捕獲異常,delete第一個new
	// 如果有很多個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是獲取到資源立即初始化,它是一種管理資源的類的設計思想,本質(zhì)是一種利用對象生命周期來管理獲取到的動態(tài)資源,避免資源泄漏,這里的資源可以是內(nèi)存、文件指針、網(wǎng)絡連接、互斥鎖等等。RAII在獲取資源時把資源委托給一個對象,接著控制對資源的訪問,資源在對象的生命周期內(nèi)始終保持有效,最后在對象析構(gòu)的時候釋放資源,這樣保障了資源的正常釋放,避免資源泄漏問題。

2. RAII像指針一樣

在對象銷毀后會正常的釋放資源

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)
{
	// 當b == 0時拋出異常
	if (b == 0)
	{
		throw "Divide by zero condition!";
	}
	else
	{
		return (double)a / (double)b;
	}
}

void Func()
{
	// 這?可以看到如果發(fā)?除0錯誤拋出異常,另外下?的array和array2沒有得到釋放。
	// 所以這?捕獲異常后并不處理異常,異常還是交給外?處理,這?捕獲了再重新拋出去。
	// 但是如果array2new的時候拋異常呢,就還需要套?層捕獲釋放邏輯,這?更好解決?案
	// 是智能指針,否則代碼太戳了
	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的設計思路,還要方便資源的訪問,所以智能指針類還像迭代器類一樣重載 operator*/operator->/operator[] 等運算符,方便訪問資源。

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

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

	// 重載運算符,模擬指針的?為,?便訪問資源
	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++標準庫智能指針的使用

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

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

	return 0;
}

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

auto_ptr是C++98時設計出來的智能指針,它的特點是拷貝時把被拷貝對象的資源的管理權(quán)轉(zhuǎn)移給拷貝對象,這是?個非常糟糕的設計,因為他會把被拷貝對象懸空(相當于被拷貝對象是空指針了),訪問報錯的問題,C++11設計出新的智能指針后,強烈建議不要使用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),為了驗證auto_ptr是否可以解決析構(gòu)兩次的問題
	~Date()
	{
		cout << "~Date()" << endl;
	}
};

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

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

	return 0;
}

C++11的智能指針

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

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

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

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

   return 0;
}

3、shared_ptr共享指針,他的特點是支持拷貝,也支持移動。如果需要拷貝的場景就需要使用他了。底層是用引用計數(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的一個問題)指針,它不同于上面的指針,它不支持RAII,也就意味著不能用它直接管理資源,weak_ptr的產(chǎn)生本質(zhì)是要解決shared_ptr的一個循環(huán)引用導致內(nèi)存泄漏的問題。

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

相關文章

最新評論