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

C++基本用法實踐之智能指針詳解

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

概述

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

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

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

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

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

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

用法舉例

參考測試項目代碼ModernCppTest/modrenc_smart_pointer.cpp主要包含:

  • 共享指針用法&聲明方式
  • 獨占指針用法&聲明方式
  • 弱指針的用法
#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)使用=運算符報錯,須使用std::move()");
				// std::unique_ptr<LocaObj> p1 = p2;
				p1 = std::move(p2);
				LOG_VAR_DESC(p1->ID, " p1->ID");

				LOG("測試被std::move的p2是否還有效,可以看到 無效");
				LOG_UNIQUE_PTR_VALID(p2);
				LOG("p2 離開作用域, ID為1的Obj沒有析構(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對象被釋放");
		p1.reset();

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

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

相關(guān)文章

  • c語言中比較特殊的輸入函數(shù)舉例詳解

    c語言中比較特殊的輸入函數(shù)舉例詳解

    C語言提供了豐富的標(biāo)準(zhǔn)庫函數(shù),用于處理各種輸入輸出操作,下面這篇文章主要介紹了c語言中比較特殊的輸入函數(shù)的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-09-09
  • C++中remove與erase區(qū)別小結(jié)

    C++中remove與erase區(qū)別小結(jié)

    remove函數(shù)和 erase函數(shù)都可以實現(xiàn)元素的刪除,本文主要介紹了C++中remove與erase區(qū)別小結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-08-08
  • 詳解C語言實現(xiàn)推箱子的基本功能

    詳解C語言實現(xiàn)推箱子的基本功能

    這篇文章主要為大家詳細(xì)介紹了C語言實現(xiàn)推箱子的基本功能的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • C++ Primer 標(biāo)準(zhǔn)庫vector示例詳解

    C++ Primer 標(biāo)準(zhǔn)庫vector示例詳解

    該文章主要介紹了C++標(biāo)準(zhǔn)庫中的vector類型,包括其定義、初始化、成員函數(shù)以及常見操作,文章詳細(xì)解釋了如何使用vector來存儲和操作對象集合,并提供了代碼示例來說明vector的使用方法,感興趣的朋友一起看看吧
    2025-03-03
  • C語言數(shù)據(jù)結(jié)構(gòu)順序表的進階講解

    C語言數(shù)據(jù)結(jié)構(gòu)順序表的進階講解

    程序中經(jīng)常需要將一組數(shù)據(jù)元素作為整體管理和使用,需要創(chuàng)建這種元素組,用變量記錄它們,傳進傳出函數(shù)等。一組數(shù)據(jù)中包含的元素個數(shù)可能發(fā)生變化,順序表則是將元素順序地存放在一塊連續(xù)的存儲區(qū)里,元素間的順序關(guān)系由它們的存儲順序自然表示
    2022-04-04
  • Qt實現(xiàn)高精度定時器

    Qt實現(xiàn)高精度定時器

    這篇文章主要為大家詳細(xì)介紹了Qt實現(xiàn)高精度定時器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • C++的QT項目打包成獨立可執(zhí)行和發(fā)布的exe文件(項目構(gòu)建過程)

    C++的QT項目打包成獨立可執(zhí)行和發(fā)布的exe文件(項目構(gòu)建過程)

    這篇文章主要介紹了C++的QT項目打包成獨立可執(zhí)行和發(fā)布的exe文件(項目構(gòu)建過程),本文通過實例圖文相結(jié)合給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-11-11
  • Qt使用SQLite數(shù)據(jù)庫實現(xiàn)數(shù)據(jù)增刪改查

    Qt使用SQLite數(shù)據(jù)庫實現(xiàn)數(shù)據(jù)增刪改查

    這篇文章主要為大家詳細(xì)介紹了Qt如何使用SQLite數(shù)據(jù)庫實現(xiàn)數(shù)據(jù)增刪改查功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起了解一下
    2023-06-06
  • C++實現(xiàn)LeetCode(209.最短子數(shù)組之和)

    C++實現(xiàn)LeetCode(209.最短子數(shù)組之和)

    這篇文章主要介紹了C++實現(xiàn)LeetCode(209.最短子數(shù)組之和),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • C語言實現(xiàn)猜數(shù)字小項目

    C語言實現(xiàn)猜數(shù)字小項目

    這篇文章主要為大家詳細(xì)介紹了C語實現(xiàn)猜數(shù)字小項目,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01

最新評論

建始县| 桃园县| 谷城县| 利川市| 定陶县| 双流县| 兴山县| 新昌县| 云龙县| 孟州市| 鄱阳县| 阳东县| 漳浦县| 永兴县| 松溪县| 金寨县| 开鲁县| 峨边| 谢通门县| 大余县| 凌海市| 吴江市| 淳化县| 双鸭山市| 大足县| 江孜县| 多伦县| 余干县| 怀集县| 桐柏县| 丁青县| 宜阳县| 峨边| 拉孜县| 苍溪县| 涞源县| 武城县| 丹凤县| 临安市| 盐源县| 宁化县|