欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

1.簡介

C++作為一門應(yīng)用廣泛的高級編程語言,卻沒有像Java、C#等語言擁有垃圾回收(Garbage Collection )機制來自動進行內(nèi)存管理,這也是C++一直被詬病的一點。C++在發(fā)展的過程中,一直致力于解決內(nèi)存泄漏,C++雖然基于效率的考慮,沒有采用垃圾回收機制,但從C++98開始,推出了智能指針(Smart Pointer)來管理內(nèi)存資源,以彌補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++的語言機制保證了,當(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)建一個空的智能指針對象。空智能指針對象不可以進行任何操作,但可以使用 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)存資源的獨占式管理,即內(nèi)存資源的所有權(quá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)存資源進行任何操作,否則會發(fā)生運行時錯誤,但我們也可以使用get()成員函數(shù)進行判空處理。

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

獨占式的內(nèi)存資源管理可以使用 unique_ptr 來完成,但是如果想對內(nèi)存資源進行共享式管理,那么 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;
}

程序編譯運行結(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.智能指針使用注意事項

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

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

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

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

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

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

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

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

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

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

相關(guān)文章

  • Matlab實現(xiàn)別踩白塊小游戲的示例代碼

    Matlab實現(xiàn)別踩白塊小游戲的示例代碼

    別踩白塊是一款音樂類休閑游戲,游戲的玩法不難,只需跟著音樂的節(jié)奏點中對的方塊即可。本文將用Matlab實現(xiàn)這一經(jīng)典游戲,感興趣的可以了解一下
    2022-03-03
  • C++中隊列的建立與操作詳細解析

    C++中隊列的建立與操作詳細解析

    隊列結(jié)構(gòu)是從數(shù)據(jù)運算來分類的,也就是說隊列結(jié)構(gòu)具有特殊的運算規(guī)則。而從數(shù)據(jù)的邏輯結(jié)構(gòu)來看,隊列結(jié)構(gòu)其實就是一種線性結(jié)構(gòu)。如果從數(shù)據(jù)的存儲結(jié)構(gòu)來進一步劃分,隊列結(jié)構(gòu)可以分成兩類
    2013-10-10
  • C++ Invalidaterect()函數(shù)作用案例詳解

    C++ Invalidaterect()函數(shù)作用案例詳解

    這篇文章主要介紹了C++ Invalidaterect()函數(shù)作用案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • VisualStudio Community2019在安裝的過程中無法進入安裝界面的解決方法

    VisualStudio Community2019在安裝的過程中無法進入安裝界面的解決方法

    這篇文章主要介紹了VisualStudio Community2019在安裝的過程中無法進入安裝界面的解決方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • C++實現(xiàn)Huffman的編解碼

    C++實現(xiàn)Huffman的編解碼

    這篇文章主要為大家詳細介紹了C++實現(xiàn)Huffman的編解碼,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • C語言代碼實現(xiàn)猜數(shù)字游戲

    C語言代碼實現(xiàn)猜數(shù)字游戲

    大家好,本篇文章主要講的是C語言代碼實現(xiàn)猜數(shù)字游戲,感興趣的同學(xué)趕快來看一看了吧,對你有幫助的話記得收藏一下
    2022-01-01
  • FFmpeg中AVIOContext的使用方法詳解

    FFmpeg中AVIOContext的使用方法詳解

    AVIOContext是FFMPEG管理輸入輸出數(shù)據(jù)的結(jié)構(gòu)體,這篇文章主要為大家詳細介紹了這個結(jié)構(gòu)體的具體使用,文中的示例代碼講解詳細,需要的可以參考一下
    2023-08-08
  • C++中const的實現(xiàn)機制深入分析

    C++中const的實現(xiàn)機制深入分析

    C語言以及C++語言中的const究竟表示什么?其具體的實現(xiàn)機制又是如何實現(xiàn)的呢?本文將對這兩個問題進行一些分析,需要了解的朋友可以參考下
    2012-12-12
  • C語言實現(xiàn)簡單彈球游戲

    C語言實現(xiàn)簡單彈球游戲

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)簡單彈球游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • Visual Studio 2019 如何新建 Win32項目的方法步驟

    Visual Studio 2019 如何新建 Win32項目的方法步驟

    這篇文章主要介紹了Visual Studio 2019 如何新建 Win32項目的方法步驟,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03

最新評論