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

一起聊聊C++中的智能指針

 更新時間:2022年07月18日 10:25:41   作者:一線碼農(nóng)  
C++?是手工管理內(nèi)存的分配和釋放,這給了程序員極大的自由度也給了我們極高的門檻,弄不好就得內(nèi)存泄露。使用智能指針能更好的管理堆內(nèi)存,本文主要給大家介紹一下c++的智能指針,需要的朋友可以參考下

一:背景

我們知道 C++ 是手工管理內(nèi)存的分配和釋放,對應(yīng)的操作符就是 new/delete 和 new[] / delete[], 這給了程序員極大的自由度也給了我們極高的門檻,弄不好就得內(nèi)存泄露,比如下面的代碼:

void test() {
	int* i = new int(10);
	*i = 10;
}

int main() {
	test();
}

這段代碼因為用了 new 而忘了 delete,導(dǎo)致在 nt heap 上分配的 i 隨著棧地址的回收而成了一塊孤懸海外的內(nèi)存占用,所以修正后的代碼如下:

void test() {
	int* i = new int(10);
	*i = 10;

	delete i;
}

int main() {
	test();
}

但這種寫法比較麻煩,智者千慮必有一失,總會有忘記加 delete 的時候,那怎么辦呢? 大家應(yīng)該知道內(nèi)存自動管理有兩種手段。

1.引用計數(shù)

代表作有 Python,PHP,還有 windows 的句柄管理。

2.引用跟蹤

代表作有 C#,JAVA 等一眾工程化語言。

因為 引用計數(shù) 實現(xiàn)比較簡單,主要就是記錄下對象的引用次數(shù),次數(shù)為 0 則釋放,所以可完全借助 類的構(gòu)造函數(shù)析構(gòu)函數(shù) 和 棧的自動回收特性 弄一個簡單的 引用計數(shù) ,對應(yīng)著如下四個關(guān)鍵詞。

  • auto_ptr
  • shared_ptr
  • unique_ptr
  • weak_ptr

接下來我們逐個聊一聊。

二:關(guān)鍵詞解析

1. auto_ptr

這是 C++ 最早出現(xiàn)一個的 簡單引用計數(shù)法,參考代碼如下:

void test() {
	auto_ptr<int> ptr = auto_ptr<int>(new int(10));
}

int main() {
	test();
}

接下來看下匯編代碼:

    auto_ptr<int> ptr = auto_ptr<int>(new int(10));
...
00771D26  call        std::auto_ptr<int>::auto_ptr<int> (07710FAh)  
00771D2B  lea         ecx,[ebp-0D8h]  
00771D31  call        std::auto_ptr<int>::~auto_ptr<int> (0771159h) 

可以看到,它分別調(diào)用了 構(gòu)造函數(shù) 和 析構(gòu)函數(shù),接下來找下 auto_ptr 這兩個函數(shù)的源碼。

class auto_ptr {

private:
	_Ty* _Myptr; // the wrapped object pointer

public:
	auto_ptr(auto_ptr_ref<_Ty> _Right) noexcept {
		_Ty* _Ptr = _Right._Ref;
		_Right._Ref = nullptr; // release old
		_Myptr = _Ptr; // reset this
	}

	~auto_ptr() noexcept {
		delete _Myptr;
	}
}

源碼一看就明白了,在構(gòu)造函數(shù)中,將 new int 的地址塞給了內(nèi)部的 _Myptr 指針,在析構(gòu)函數(shù)中對 _Myptr 進(jìn)行 delete ,真好,這樣就不用整天擔(dān)心有沒有加 delete 啦。

值得注意的是,現(xiàn)在 C++ 不推薦這個了,而是建議使用新增的:shared_ptr,unique_ptr,weak_ptr, 怎么說呢? auto_ptr 有一個不好處理的問題,就是現(xiàn)實開發(fā)中會出現(xiàn)這么個場景,多個 ptr 指向同一個 引用,如下圖:

2. auto_ptr 多引用問題

方式1:

定義三個 ptr,然后包裝同一個 new int 地址,參考代碼如下:

void test() {
	int* i = new int(10);

	auto_ptr<int> ptr1(i);
	auto_ptr<int> ptr2(i);
	auto_ptr<int> ptr3(i);
}

這種寫法有沒有問題呢? 肯定有問題啦,還記得 auto_ptr 的析構(gòu)是 delete 嗎? 對同一塊內(nèi)存多次 delete 會拋異常的,如下圖所示:

方式2:

既然定義三個有問題, 那就用賦值運算符= 讓 ptr1,ptr2,ptr3 指向同一個地址是不是就可以啦? 參考代碼如下:

void test() {
	int* i = new int(10);

	auto_ptr<int> ptr1(i);
	auto_ptr<int> ptr2 = ptr1;
	auto_ptr<int> ptr3 = ptr2;
}

int main() {
	test();
}

那這段代碼有沒有問題呢? 有沒有問題得要看 = 運算符是如何重寫的,扒一下源碼看看。

template <class _Other>
auto_ptr& operator=(auto_ptr<_Other>& _Right) noexcept {
	reset(_Right.release());
	return *this;
}
_Ty* release() noexcept {
	_Ty* _Tmp = _Myptr;
	_Myptr = nullptr;
	return _Tmp;
}

從源碼看有一個很惡心的點,他會將 _Right 下的 _Myptr 設(shè)為 nullptr,也就是說此時的 ptr1 報廢了,言外之意就是后續(xù)再訪問 ptr1 會拋 訪問違例。

哈哈,C++里面的專業(yè)術(shù)語叫 控制權(quán)轉(zhuǎn)移。

以上就是一起聊聊C++中的智能指針的詳細(xì)內(nèi)容,更多關(guān)于C++智能指針的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C語言實現(xiàn)簡單圖書管理系統(tǒng)

    C語言實現(xiàn)簡單圖書管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語言實現(xiàn)圖書管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • C++ 多線程編程建議之 C++ 對多線程/并發(fā)的支持(下)

    C++ 多線程編程建議之 C++ 對多線程/并發(fā)的支持(下)

    這篇文章主要介紹的是 C++ 多線程編程建議之 C++ 對多線程/并發(fā)的支持的相關(guān)資料,承接前文 現(xiàn)代 C++ 對多線程/并發(fā)的支持,接下來我們看看回發(fā)生什么吧
    2021-10-10
  • operator new在C++中的各種寫法總結(jié)

    operator new在C++中的各種寫法總結(jié)

    這篇文章并不是一個綜合的手冊,而是一個C++中各種內(nèi)存分配方法的概述。它面向已經(jīng)很熟悉C++語言的讀者
    2013-09-09
  • C++中的命名空間詳細(xì)介紹

    C++中的命名空間詳細(xì)介紹

    大家好,本篇文章主要講的是C++中的命名空間詳細(xì)介紹,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-02-02
  • opencv平均背景法詳解

    opencv平均背景法詳解

    這篇文章主要為大家詳細(xì)介紹了opencv平均背景法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • 基于Qt實現(xiàn)駕??颇靠荚囅到y(tǒng)的示例代碼

    基于Qt實現(xiàn)駕??颇靠荚囅到y(tǒng)的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何基于Qt實現(xiàn)駕??颇靠荚囅到y(tǒng),文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)Qt有一定幫助,需要的可以參考一下
    2022-07-07
  • C++中std::thread線程用法

    C++中std::thread線程用法

    本文主要介紹了C++中std::thread線程用法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • C++中opencv4.1.0環(huán)境配置的詳細(xì)過程

    C++中opencv4.1.0環(huán)境配置的詳細(xì)過程

    這篇文章主要介紹了C++中opencv4.1.0環(huán)境配置的詳細(xì)過程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-10-10
  • 探討C++中不能聲明為虛函數(shù)的有哪些函數(shù)

    探討C++中不能聲明為虛函數(shù)的有哪些函數(shù)

    下面小編就為大家?guī)硪黄接慍++中不能聲明為虛函數(shù)的有哪些函數(shù)。希望對大家有所幫助。一起跟隨小編過來看看吧,祝大家游戲愉快哦
    2017-01-01
  • Opencv實現(xiàn)圖像灰度線性變換

    Opencv實現(xiàn)圖像灰度線性變換

    這篇文章主要為大家詳細(xì)介紹了Opencv實現(xiàn)圖像灰度線性變換,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-05-05

最新評論

镇平县| 无棣县| 开鲁县| 来安县| 德兴市| 紫阳县| 都江堰市| 渝北区| 台州市| 固阳县| 蒙自县| 敖汉旗| 邵阳县| 蒲城县| 东辽县| 津市市| 芦山县| 页游| 庐江县| 丰台区| 扬州市| 西安市| 健康| 象山县| 阳朔县| 安多县| 贞丰县| 弥渡县| 北碚区| 封开县| 得荣县| 邛崃市| 镇坪县| 林周县| 定日县| 平塘县| 钟祥市| 金乡县| 海门市| 三都| 同江市|