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

一起聊聊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,導致在 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 進行 delete ,真好,這樣就不用整天擔心有沒有加 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++中的智能指針的詳細內(nèi)容,更多關(guān)于C++智能指針的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C語言實現(xiàn)密碼本

    C語言實現(xiàn)密碼本

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)密碼本,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • C語言實現(xiàn)頁面置換算法(FIFO、LRU)

    C語言實現(xiàn)頁面置換算法(FIFO、LRU)

    這篇文章主要介紹了通過C語言實現(xiàn)的兩種頁面置換算法:先進先出(FIFO)頁面置換算法和最近最久未使用(LRU)頁面置換算法。文中的代碼具有一定的學習或工作價值,快來跟隨小編學習一下吧
    2021-12-12
  • strcat 函數(shù)的使用指南

    strcat 函數(shù)的使用指南

    strcat是連接字符串的函數(shù)。函數(shù)返回指針,兩個參數(shù)都是指針,第一個參數(shù)所指向的內(nèi)存的地址必須能容納兩個字符串連接后的大小。
    2015-09-09
  • C語言實現(xiàn)“幸運數(shù)”的實例詳解

    C語言實現(xiàn)“幸運數(shù)”的實例詳解

    這篇文章主要介紹了C語言實現(xiàn)“幸運數(shù)”的實例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-07-07
  • C++中的四種類型轉(zhuǎn)換

    C++中的四種類型轉(zhuǎn)換

    類型轉(zhuǎn)換有c風格的,當然還有c++風格的。c風格的轉(zhuǎn)換的格式很簡單(TYPE)EXPRESSION,但是c風格的類型轉(zhuǎn)換有不少的缺點,有的時候用c風格的轉(zhuǎn)換是不合適的,因為它可以在任意類型之間轉(zhuǎn)換,
    2015-08-08
  • 基于字符串移位包含的問題詳解

    基于字符串移位包含的問題詳解

    本篇文章是對字符串移位包含的問題的解決方法進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • C語言中sizeof函數(shù)的基本使用總結(jié)

    C語言中sizeof函數(shù)的基本使用總結(jié)

    這篇文章主要給大家介紹了關(guān)于C語言中sizeof函數(shù)的基本使用的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。
    2018-03-03
  • C++11中union的使用方法示例

    C++11中union的使用方法示例

    這篇文章主要給大家介紹了關(guān)于C++11中union的使用方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-09-09
  • 利用Matlab實現(xiàn)時域分析功能的示例詳解

    利用Matlab實現(xiàn)時域分析功能的示例詳解

    利用MATLAB可以方便地進行控制系統(tǒng)的時域分析。這篇文章主要通過簡單的示例為大家介紹了Matlab進行時域分析的具體操作,需要的可以參考一下
    2023-02-02
  • C語言*與&在操作線性表的作用詳解

    C語言*與&在操作線性表的作用詳解

    本文主要介紹了C語言*與&在操作線性表的作用詳解,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-10-10

最新評論