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

C++如何用智能指針管理內(nèi)存資源

 更新時間:2020年08月31日 07:00:37   作者:Dabelv  
這篇文章主要介紹了C++如何用智能指針管理內(nèi)存資源,幫助大家更好的理解和使用c++開發(fā),感興趣的朋友可以了解下

1.簡介

C++作為一門應(yīng)用廣泛的高級編程語言,卻沒有像Java、C#等語言擁有垃圾回收(Garbage Collection )機(jī)制來自動進(jìn)行內(nèi)存管理,這也是C++一直被詬病的一點(diǎn)。C++在發(fā)展的過程中,一直致力于解決內(nèi)存泄漏,C++雖然基于效率的考慮,沒有采用垃圾回收機(jī)制,但從C++98開始,推出了智能指針(Smart Pointer)來管理內(nèi)存資源,以彌補(bǔ)C++在內(nèi)存管理上的技術(shù)空白。

智能指針是C++程序員們一件管理內(nèi)存的利器,使用智能指針管理內(nèi)存資源,實際上就是將申請的內(nèi)存資源交由智能指針來管理,是RAII技術(shù)的一種實現(xiàn)。RAII是C++的之父Bjarne Stroustrup教授提出的概念,RAII全稱是“Resource Acquisition is Initialization”,直譯過來是“資源獲取即初始化”,也就是說在構(gòu)造函數(shù)中獲取資源,在析構(gòu)函數(shù)中釋放資源。因為C++的語言機(jī)制保證了,當(dāng)一個對象創(chuàng)建的時候,自動調(diào)用構(gòu)造函數(shù),當(dāng)對象超出作用域的時候會自動調(diào)用析構(gòu)函數(shù)。所以,在RAII的指導(dǎo)下,我們應(yīng)該使用類來管理資源,將資源和對象的生命周期綁定。

“資源獲取即初始化”,在使用智能指針管理內(nèi)存資源時,“資源”指的是通過new或malloc申請的內(nèi)存資源,“初始化”指的是使用申請的內(nèi)存資源來初始化棧上的智能指針類對象。使用智能指針管理內(nèi)存資源的好處顯而易見,通過智能指針對象在聲明周期結(jié)束時,自動調(diào)用析構(gòu)函數(shù),在析構(gòu)函數(shù)中完成對內(nèi)存資源的釋放,即自動的調(diào)用內(nèi)存資源的釋放代碼,避免因忘記對內(nèi)存資源的釋放導(dǎo)致內(nèi)存泄漏。

2.實例

下面看一個使用由C++11引入的智能指針unique_ptr來管理內(nèi)存資源的例子。

#include <memory>
#include <iostream>
using namespace std;

class A
{
public:
	A() {}
	~A() 
	{
		cout<<"A's destructor"<<endl;
	}
	void Hello() 
	{
		cout<<"use smart pointer to manage memory resources as far as possible"<<endl;
	}
};

int main()
{
	unique_ptr<A> pA(new A);
	pA->Hello();
	return 0;
}

程序輸出:

use smart pointer to manage memory resources as far as possible
A's destructor

可見在main()函數(shù)結(jié)束后,類A的析構(gòu)函數(shù)被自動調(diào)用,完成了內(nèi)存資源了釋放。

在創(chuàng)建智能指針對象時,也可以暫時不指定內(nèi)存資源,先創(chuàng)建一個空的智能指針對象??罩悄苤羔槍ο蟛豢梢赃M(jìn)行任何操作,但可以使用 get() 成員函數(shù)來判斷是否存在內(nèi)存資源,如果為空則可以指定內(nèi)存資源。類似于如下操作:

unique_ptr<int> pInt;
if (pInt.get()==nullptr)
{
	pInt.reset(new int(8));
	cout<<*pInt<<endl;
}

使用 unique_ptr 智能指針來管理內(nèi)存資源時,是對內(nèi)存資源的獨(dú)占式管理,即內(nèi)存資源的所有權(quán)不能進(jìn)行共享,同一時刻只能有一個 unique_ptr 對象占有某個內(nèi)存資源。如果發(fā)生賦值或拷貝構(gòu)造,則會在編譯期報錯,因為unique_ptr禁止了拷貝語義,提高了代碼的安全性。

unique_ptr<int> pInt(new int(8));
unique_ptr<int> pInt1=pInt;	//編譯報錯
unique_ptr<int> pInt2(pInt);	//編譯報錯

當(dāng)然,可以通過移動語義完成內(nèi)存資源的所有權(quán)轉(zhuǎn)移,轉(zhuǎn)移之后,原智能指針對象變?yōu)榭罩悄苤羔槍ο?,不能再對?nèi)存資源進(jìn)行任何操作,否則會發(fā)生運(yùn)行時錯誤,但我們也可以使用get()成員函數(shù)進(jìn)行判空處理。

unique_ptr<int> pInt(new int(8));
unique_ptr<int> pInt1=std::move(pInt);		//轉(zhuǎn)移所有權(quán)
*pInt=6;																//對空智能指針進(jìn)行賦值操作將報運(yùn)行時錯誤
if(!pInt.get())														//判空處理更安全
{
	*pInt=6;
}

獨(dú)占式的內(nèi)存資源管理可以使用 unique_ptr 來完成,但是如果想對內(nèi)存資源進(jìn)行共享式管理,那么 unique_ptr 就無能為力了。shared_prt 使用引用計數(shù)來實現(xiàn)對內(nèi)存資源的共享式管理,當(dāng)對內(nèi)存資源的引用計數(shù)變?yōu)?時,由最后一個對內(nèi)存資源擁有管理權(quán)的智能指針對象完成對內(nèi)存資源的釋放。

#include <memory>
#include <iostream>
using namespace std;

class A
{
public:
	A() {}
	~A()
	{
		cout << "A's destructor" << endl;
	}
	void Hello()
	{
		cout << "use smart pointer to manage memory resources as far as possible" << endl;
	}
};

int main()
{
	shared_ptr<A> spInt(new A);		//接管內(nèi)存資源
	cout << "reference count "<<spInt.use_count() << endl;
	shared_ptr<A> spInt1 = spInt;	//spInt1獲取內(nèi)存資源的管理權(quán)
	spInt1->Hello();
	cout << "reference count " << spInt.use_count() << endl;
	spInt1.reset();						//spInt1放棄對內(nèi)存資源的管理權(quán)
	cout << "reference count " << spInt.use_count() << endl;
}

程序編譯運(yùn)行結(jié)果:

reference count 1
use smart pointer to manage memory resources as far as possible
reference count 2
reference count 1
A's destructor

3.智能指針使用注意事項

智能指針雖然增強(qiáng)了安全性,避免了潛在的內(nèi)存泄漏,但是我們在使用時還是應(yīng)該遵守一定的規(guī)則,以保證代碼的健壯性。
(1)smart_ptr<T> 不等于 T*,使用時不能完全按照T*來使用。因為smart_ptr<T>本質(zhì)上是類對象,一個用于管理內(nèi)存資源的智能指針類對象,而T*是一個指向類型T的指針,二者不能隨意地轉(zhuǎn)換和賦值;

(2)使用獨(dú)立的語句將newed對象置入智能指針,因為使用臨時智能指針對象可能會引發(fā)內(nèi)存泄漏。比如下面的語句:

process(shared_ptr<A>(new A),foo());

實際上對 process() 函數(shù)調(diào)用時編譯器需要完成如下三步為process()準(zhǔn)備好實參。

(1)調(diào)用函數(shù)foo();
(2)執(zhí)行new A表達(dá)式;
(3)調(diào)用shared_ptr<A>構(gòu)造函數(shù),初始化智能指針對象。

實際上,不同的編譯器在執(zhí)行上述三個語句時可能會有不同的順序,如果編譯器將(2.2)放在(2.1)之前執(zhí)行,執(zhí)行順序如下:

(1)執(zhí)行new A表達(dá)式;
(2)調(diào)用函數(shù)foo();
(3)調(diào)用shared_ptr<A>構(gòu)造函數(shù),初始化智能指針對象。

如果在調(diào)用函數(shù)foo()時拋出異常,那么new A表達(dá)式產(chǎn)生的指向堆對象指針將會丟失,于是產(chǎn)生了內(nèi)存泄漏。解決辦法就是使用獨(dú)立的語句將newed對象置入智能指針,做法如下:

shared_ptr<A> spA(new A);
process(spA,foo());

以上就是C++如何用智能指針管理內(nèi)存資源的詳細(xì)內(nèi)容,更多關(guān)于c++ 智能指針管理內(nèi)存的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C++實現(xiàn)簡單插件機(jī)制原理解析

    C++實現(xiàn)簡單插件機(jī)制原理解析

    這篇文章主要介紹了C++實現(xiàn)簡單插件機(jī)制原理解析,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-02-02
  • C語言中回調(diào)函數(shù)的使用詳情

    C語言中回調(diào)函數(shù)的使用詳情

    這篇文章主要介紹了C語言中回調(diào)函數(shù)的使用詳情,閱讀下文我們將學(xué)習(xí)到架構(gòu)的核心理念和需、回調(diào)函數(shù)的作用、回調(diào)函數(shù)的程序編寫等內(nèi)容,需要的小伙伴可以參考一下
    2022-03-03
  • C語言實現(xiàn)打印九九乘法表的四種方式小結(jié)

    C語言實現(xiàn)打印九九乘法表的四種方式小結(jié)

    這篇文章主要為大家介紹了C語言實現(xiàn)打印九九乘法表的四種方式,文中的示例代碼講解詳細(xì),簡潔易懂,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-07-07
  • C語言每日練習(xí)之二叉堆

    C語言每日練習(xí)之二叉堆

    這篇文章主要為大家介紹了C語言二叉堆,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-01-01
  • C語言實現(xiàn)查詢自動售貨機(jī)中的商品價格【實例分享】

    C語言實現(xiàn)查詢自動售貨機(jī)中的商品價格【實例分享】

    本文主要介紹了C語言實現(xiàn)查詢自動售貨機(jī)中的商品價格的相關(guān)資料。具有很好的參考價值。下面跟著小編一起來看下吧
    2017-04-04
  • C++基礎(chǔ)學(xué)生管理系統(tǒng)

    C++基礎(chǔ)學(xué)生管理系統(tǒng)

    這篇文章主要介紹了C++基礎(chǔ)學(xué)生管理系統(tǒng)的相關(guān)資料,包括了文件處理代碼,鏈表處理代碼,以及自定義代碼,主函數(shù)自定義,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-04-04
  • 詳解C/C++ QT QChart 繪制組件應(yīng)用

    詳解C/C++ QT QChart 繪制組件應(yīng)用

    Qtcharts 組件基于GraphicsView模式實現(xiàn),其核心是QChartView和QChart的二次封裝版。本文重點(diǎn)給大家介紹C/C++ QT QChart 繪制組件應(yīng)用的相關(guān)知識,感興趣的朋友一起看看吧
    2021-11-11
  • 使用C語言中的time函數(shù)獲取系統(tǒng)時間

    使用C語言中的time函數(shù)獲取系統(tǒng)時間

    在C語言中可以使用time函數(shù)來獲取系統(tǒng)時間,以下對time函數(shù)進(jìn)行了介紹,需要的朋友可以過來參考下
    2013-07-07
  • 餐館點(diǎn)菜系統(tǒng)C語言源代碼

    餐館點(diǎn)菜系統(tǒng)C語言源代碼

    這篇文章主要為大家詳細(xì)介紹了餐館點(diǎn)菜系統(tǒng)C語言源代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • 淺析C語言中printf(),sprintf(),scanf(),sscanf()的用法和區(qū)別

    淺析C語言中printf(),sprintf(),scanf(),sscanf()的用法和區(qū)別

    以下是對C語言中printf(),sprintf(),scanf(),sscanf()的用法以及區(qū)別進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以參考下
    2013-07-07

最新評論

邛崃市| 广宁县| 买车| 南和县| 尼木县| 阳江市| 乐业县| 株洲县| 海南省| 泸州市| 四川省| 绥芬河市| 白玉县| 灵丘县| 彭泽县| 靖安县| 米脂县| 天门市| 新河县| 凤翔县| 海林市| 米脂县| 滦南县| 孝感市| 仁布县| 黄冈市| 林州市| 邵阳县| 临沧市| 凤翔县| 墨玉县| 南通市| 青浦区| 天长市| 永城市| 简阳市| 女性| 凌海市| 大丰市| 二手房| 吉木乃县|