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

C++基本用法實(shí)踐之智能指針詳解

 更新時(shí)間:2023年07月17日 11:28:04   作者:寡人正在Coding  
為了減少手動(dòng)管理內(nèi)存帶來(lái)的困擾,c++提出了智能指針,可以幫助我們進(jìn)行內(nèi)存管理,下面小編就來(lái)和大家簡(jiǎn)單聊聊C++中智能指針的基本用法吧

概述

c++效率較高的一個(gè)原因是我們可以自己定制策略手動(dòng)申請(qǐng)和釋放內(nèi)存,當(dāng)然,也伴隨著開發(fā)效率降低和內(nèi)存泄漏的風(fēng)險(xiǎn)。為了減少手動(dòng)管理內(nèi)存帶來(lái)的困擾,c++提出了智能指針,可以幫助我們進(jìn)行內(nèi)存管理,有三種:

  • std::unique_ptr 是一種獨(dú)占所有權(quán)的智能指針,它不允許多個(gè)指針指向同一個(gè)對(duì)象。std::unique_ptr 是一種輕量級(jí)的智能指針,不需要額外的開銷,因此在你不需要共享所有權(quán)的情況下,應(yīng)優(yōu)先使用 std::unique_ptr。
  • std::shared_ptr 是一種可以共享所有權(quán)的智能指針。多個(gè) std::shared_ptr 可以指向同一個(gè)對(duì)象,該對(duì)象只有在最后一個(gè)指向它的 std::shared_ptr 被銷毀時(shí)才會(huì)被刪除。std::shared_ptr 使用引用計(jì)數(shù)來(lái)跟蹤有多少個(gè)智能指針指向同一個(gè)對(duì)象。
  • std::weak_ptr 是一種弱引用智能指針,它可以指向 std::shared_ptr 所管理的對(duì)象,但它不會(huì)增加該對(duì)象的引用計(jì)數(shù)。這對(duì)于解決 std::shared_ptr 的循環(huán)引用問(wèn)題很有用。

智能指針的類型決定了何時(shí)銷毀和釋放內(nèi)存。當(dāng)智能指針的生命周期結(jié)束時(shí),它會(huì)自動(dòng)清理其所有權(quán)的內(nèi)存。這就避免了內(nèi)存泄漏,使代碼更安全、更健壯。
但是智能指針的使用,也要注意一些問(wèn)題:

  • 智能指針并不能自動(dòng)解決循環(huán)引用的問(wèn)題,需要手動(dòng)在合適的場(chǎng)合使用std::weak_ptr弱指針
  • 智能指針的使用是“傳染性”的,如果使用智能指針,要考慮好整個(gè)邏輯鏈條都使用智能指針而不是原生的指針
  • 從實(shí)際項(xiàng)目使用上看,一些比較上層的模塊使用智能指針,更加方便,而在底層模塊更多的還是使用原生的指針,我想大概因?yàn)橹悄苤羔樢彩菚?huì)帶來(lái)一些開銷而且可能和一些內(nèi)存管理策略沖突(如某些優(yōu)化內(nèi)存策略可能不使用指針,而使用句柄來(lái)指向?qū)ο螅?/li>

智能指針是一個(gè)對(duì)象,實(shí)現(xiàn)是非入侵式的。關(guān)于他們的大概的原理:

  • std::unique_ptr 它包含一個(gè)原生指針,并在其析構(gòu)函數(shù)中刪除這個(gè)指針。std::unique_ptr還重載了->*運(yùn)算符,所以可以像使用原生指針一樣使用std::unique_ptr
  • std::shared_ptr 的實(shí)現(xiàn)則相對(duì)復(fù)雜一些。除了存儲(chǔ)原生指針,std::shared_ptr還需要存儲(chǔ)一個(gè)引用計(jì)數(shù)。每次創(chuàng)建一個(gè)新的std::shared_ptr或者調(diào)用std::shared_ptr的拷貝構(gòu)造函數(shù)或賦值運(yùn)算符時(shí),引用計(jì)數(shù)就會(huì)增加。每次銷毀一個(gè)std::shared_ptr時(shí),引用計(jì)數(shù)就會(huì)減少。只有當(dāng)引用計(jì)數(shù)降到0時(shí),才會(huì)刪除原生指針。類似的還要處理若引用。此外,引用計(jì)數(shù)還要保證線程安全。

用法舉例

參考測(cè)試項(xiàng)目代碼ModernCppTest/modrenc_smart_pointer.cpp主要包含:

  • 共享指針用法&聲明方式
  • 獨(dú)占指針用法&聲明方式
  • 弱指針的用法
#include "ModernCppTestHeader.h"
#include <memory>

#define LOG_UNIQUE_PTR_VALID(ptr) if(ptr) LOG(#ptr << " unique_ptr valid"); else LOG(#ptr << " unique_ptr invalid")
#define LOG_WEAK_PTR_IF_VALID(ptr, exp) if(auto tp = p2.lock()) exp else LOG(#ptr << " weak_ptr invalid")

namespace n_smart_pointer {
	class Obj {
	public:
		Obj(int ID) : ID(ID) { LOG("Obj addr " << this << " ID " << ID << " Create"); }
		~Obj() { LOG("Obj addr " << this << " ID " << ID << " Release"); }

		int ID;
	};

	class Item {};
}

using LocaObj = n_smart_pointer::Obj;

void smart_pointer_test()
{
	LOG_FUNC();


	LOG_TAG("std::shared_ptr 共享指針");
	{
		{
			std::shared_ptr<LocaObj> p1 = std::make_shared<LocaObj>(1);
			{
				std::shared_ptr<LocaObj> p2 = p1;
				LOG_VAR_DESC(p1->ID, " p1->ID");
				LOG_VAR_DESC(p2->ID, " p2->ID");
				LOG("p2 離開作用域");
			}
			LOG("p1 離開作用域");
		}
	}


	LOG_TAG("std::shared_ptr 共享指針的聲明方式");
	{
		std::shared_ptr<LocaObj> p1(new LocaObj(1));
		std::shared_ptr<LocaObj> p2 = std::make_shared<LocaObj>(2);
		std::shared_ptr<LocaObj> p3(p2);
	}


	LOG_TAG("std::unique_ptr 唯一指針");
	{
		{
			std::unique_ptr<LocaObj> p1;
			{
				std::unique_ptr<LocaObj> p2 = std::make_unique<LocaObj>(1);
				LOG_VAR_DESC(p2->ID, " p2->ID");

				LOG("唯一指針轉(zhuǎn)移控制權(quán)使用=運(yùn)算符報(bào)錯(cuò),須使用std::move()");
				// std::unique_ptr<LocaObj> p1 = p2;
				p1 = std::move(p2);
				LOG_VAR_DESC(p1->ID, " p1->ID");

				LOG("測(cè)試被std::move的p2是否還有效,可以看到 無(wú)效");
				LOG_UNIQUE_PTR_VALID(p2);
				LOG("p2 離開作用域, ID為1的Obj沒(méi)有析構(gòu)");
			}

			LOG("p1 離開作用域, ID為1的Obj析構(gòu)");
		}
	}


	LOG_TAG("std::unique_ptr 唯一指針的聲明方式");
	{
		std::unique_ptr<LocaObj> p1(new LocaObj(1));
		std::unique_ptr<LocaObj> p2 = std::make_unique<LocaObj>(2);
		std::unique_ptr<LocaObj> p3(std::move(p2));
	}


	LOG_TAG("std::weak_ptr 弱指針");
	{
		std::shared_ptr<LocaObj> p1 = std::make_shared<LocaObj>(1);
		std::weak_ptr<LocaObj> p2 = p1;

		LOG_VAR_DESC(p1->ID, " p1->ID");
		LOG_WEAK_PTR_IF_VALID(p2, LOG_VAR_DESC(tp->ID, " p2->ID"););

		LOG("p1 reset Obj對(duì)象被釋放");
		p1.reset();

		LOG("p2 弱指針失效");
		LOG_WEAK_PTR_IF_VALID(p2, LOG_VAR_DESC(tp->ID, " p2->ID"););
	}
}

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

相關(guān)文章

  • 使用VScode搭建ROS開發(fā)環(huán)境的教程詳解

    使用VScode搭建ROS開發(fā)環(huán)境的教程詳解

    這篇文章主要介紹了使用VScode搭建ROS開發(fā)環(huán)境,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-08-08
  • C++中傳值、傳地址和傳引用究竟有哪些區(qū)別

    C++中傳值、傳地址和傳引用究竟有哪些區(qū)別

    指針是一個(gè)變量,只不過(guò)這個(gè)變量存儲(chǔ)的是一個(gè)地址,指向內(nèi)存的一個(gè)存儲(chǔ)單元,而引用跟原來(lái)的變量實(shí)質(zhì)上是同一個(gè)東西,只不過(guò)是原變量的一個(gè)別名而已,這篇文章主要給大家介紹了關(guān)于C++中傳值、傳地址和傳引用究竟有哪些區(qū)別的相關(guān)資料,需要的朋友可以參考下
    2021-07-07
  • C/C++讀寫文本文件、二進(jìn)制文件的方法

    C/C++讀寫文本文件、二進(jìn)制文件的方法

    今天小編就為大家分享一篇C/C++讀寫文本文件、二進(jìn)制文件的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-07-07
  • C++實(shí)現(xiàn)LeetCode(52.N皇后問(wèn)題之二)

    C++實(shí)現(xiàn)LeetCode(52.N皇后問(wèn)題之二)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(52.N皇后問(wèn)題之二),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C++ deque容器的用法詳解

    C++ deque容器的用法詳解

    在處理一些數(shù)組的事情,所以隨手保留一下Deque容器的使用方法很有必要,接下來(lái)通過(guò)本文給大家重點(diǎn)介紹C++ deque容器的用法及deque和vector的區(qū)別講解,感興趣的朋友跟隨小編一起看看吧
    2021-05-05
  • 一文搞懂Codec2框架解析

    一文搞懂Codec2框架解析

    這篇文章主要介紹了Codec2框架解析,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-09-09
  • C語(yǔ)言代碼實(shí)現(xiàn)三子棋游戲

    C語(yǔ)言代碼實(shí)現(xiàn)三子棋游戲

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言代碼實(shí)現(xiàn)三子棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • C++中的變長(zhǎng)參數(shù)深入理解

    C++中的變長(zhǎng)參數(shù)深入理解

    變長(zhǎng)參數(shù)的函數(shù),即參數(shù)個(gè)數(shù)可變、參數(shù)類型不定的函數(shù)。設(shè)計(jì)一個(gè)參數(shù)個(gè)數(shù)可變、參數(shù)類型不定的函數(shù)是可能的,最常見的例子是printf函數(shù)、scanf函數(shù)和高級(jí)語(yǔ)言的Format函數(shù)。最近的一個(gè)項(xiàng)目中就遇到這么一個(gè)相關(guān)的問(wèn)題,感興趣的朋友們下面來(lái)一起看看吧。
    2016-10-10
  • floyd算法實(shí)現(xiàn)思路及實(shí)例代碼

    floyd算法實(shí)現(xiàn)思路及實(shí)例代碼

    這篇文章主要介紹了floyd算法實(shí)現(xiàn)思路及實(shí)例代碼,有需要的朋友可以參考一下
    2014-01-01
  • 2048小游戲C語(yǔ)言實(shí)現(xiàn)代碼

    2048小游戲C語(yǔ)言實(shí)現(xiàn)代碼

    這篇文章主要為大家詳細(xì)介紹了2048小游戲C語(yǔ)言實(shí)現(xiàn)代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-05-05

最新評(píng)論