首页 > 其他分享 >十三、指针和引用(三)

十三、指针和引用(三)

时间:2023-11-22 23:11:23浏览次数:28  
标签:std ptrA 十三 int 引用 shared unique 指针

十三、指针和引用(三)

1、std::unique_ptr(唯一智能指针)

1)概念

std::unique_ptr是所谓的智能指针的一种,主要目的是为了解决原生指针安全性不足的弊端

//std::unique_ptr指针的声明语法
std::unqiue_ptr<类型>变量名称{};

//示例
std::unique_ptr<int>ptrA{std::make_unique<int>(150)}; // 申请一个具有1个int类型大小的指针,值为150
std::cout<<*ptrA;  //指针使用

std::unique_ptr<int[]>ptrB{new int[5]}; //C++14之前的写法,申请一个具有5个int类型大小的指针
std::unique_ptr<int[]>ptrB{std::make_unique<int[]>(10)};   //申请一个具有5个int类型大小的指针
ptrB[0]=250;  //指针使用,此声明方法,只能通过数组访问

2)唯一智能指针特性

std::unique_ptr的特点是该指针具有唯一性,因此无法让两个std::unique_ptr指针存放相同的内存地址,如下:

std::unique_ptr<int>ptrA{std::make_unique<int>(150)};
std::unique_ptr<int>ptrB{};
//ptrA=ptrB;      //错误,无法直接赋值

#include <iostream>

int main()
{
	int* a = new int[5];
	std::unique_ptr<int[]>intptr{ std::make_unique<int[]>(5) };     //申请一个具有5个int类型大小的指针

	std::unique_ptr<int>intptrA{ std::make_unique<int>(5) };  // 申请一个具有1个int类型大小的指针,值为5

	std::cout << intptr << " " << intptr[0]<<std::endl;        //013D5C98 0
	std::cout << intptrA << " " << *intptrA << std::endl;      //013DEC10 5
}

3)reset()用法

​ reset将会释放std::unique_ptr的内存空间,并且将std::unique_ptr设置为nullptr;

//reset()用法示例
std::unique_ptr<int>ptrA{std::make_unique<int>(150)};
ptrA.reset();  //此时ptrA的内存空间被释放,ptrA的值设置成了nullptr
//reset()示例
#include <iostream>

int main()
{
	int* a = new int[5];
	delete[] a;        //释放new申请的内存空间

	std::unique_ptr<int>ptrA{ std::make_unique<int>(100) };
	std::cout << "释放内存前的地址:"<<ptrA << std::endl;
	ptrA.reset();           //释放唯一智能指针
	std::cout << "释放内存后的地址:" << ptrA << std::endl;
}

4)get()用法:返回一个std::unique_ptr的指针

//get()用法
std::unique_ptr<int>ptrA{std::make_unique<int>(150)};
int*p = ptrA.get();     //相当于将ptrA申请时的内存赋值给p

5)release()用法

relsease将会返回std::unique_ptr的指针,并且将std::unique_ptr设置为nullptr,但是注意release并不会释放其占用的内存空间

//relseae()用法
std::unique_ptr<int>ptrA{std::make_unique<int>(150)};
int* p = ptrA.release(); 
//此时ptrA占用的内存空间没有被释放,ptrA的值设置成了nullptr,p等于ptrA申请内存时的地址
//release只是将申请的内存地址设置为了0,并没有释放,并且将原理的地址进行了返回
#include <iostream>

int main()
{

	int* a = new int[5];
	std::unique_ptr<int>ptrA{ std::make_unique<int>(100) };
	std::cout << "release前的地址:" << ptrA << std::endl;
	a = ptrA.release();
	std::cout << "release后的地址:" << ptrA << std::endl;
	std::cout << "a的地址:" << a << std::endl;
}

6)唯一智能指针的转移(move)

​ std::unique_ptr指针因为具有唯一性,因此不能被复制,但是可以转移

//唯一智能指针转移语法
转移后的指针变量=std::move(转移前的指针变量);

//示例
std::unique_ptr<int>ptrA{std::make_unique<int>(150)};
std::unique_ptr<int>ptrB;
ptrB=std::move(ptrA);  //将ptrA的地址转移到ptrB,转移后ptrA被设置为nullptr

2、std::shared_per(共享智能指针)

1)共享智能指针语法

//共享智能指针语法
std::shared_ptr<类型>变量名称{};

//示例
std::shared_ptr<int>ptrA{};
std::shared_ptr<int>ptrB{std::make_shared<int>(5)};

//注:std::make_shared不支持新式的数组的定义方式,只能通过new的方式
std::shared_ptr<int[]>ptr{new int[5]{1,2,3,4,5}};
//共享智能指针的定义及使用
#include <iostream>

int main()
{
	int* a{};
	std::shared_ptr<int>ptrA{ std::make_shared<int>(5) };
	std::shared_ptr<int>ptrB{ ptrA };       //共享ptrA的内存地址
	std::shared_ptr<int>ptrC{ ptrA };

	std::cout << "ptrA的内存地址为:" << ptrA << std::endl;
	std::cout << "ptrB的内存地址为:" << ptrB << std::endl;
	std::cout << "ptrA的内存地址为:" << ptrC << std::endl;
	std::cout << "\n";
	std::cout << "ptrA的值为:" << *ptrA << std::endl;
	std::cout << "ptrB的值为:" << *ptrB << std::endl;
	
}

2)共享智能指针特性

​ 可以有多个std::shared_ptr指向同一地址,同一地址下只有当最后一个std::shared_ptr释放的时候,才会释放其占用的内存空间,std::shared_ptr会记录当前地址有多少个智能指针调用

3)统计共享指针当前有多少个对象调用(use_count)

//统计共享指针当前有多少个对象调用
long std::shared_ptr.use_count();  

.user_count();  //会返回当前指针共有多少个对象调用
//use.count()用法示例
#include <iostream>

int main()
{
	int* a{};
	std::shared_ptr<int>ptrA{ std::make_shared<int>(5) };
	std::shared_ptr<int>ptrB{ ptrA };       //共享ptrA的内存地址
	std::shared_ptr<int>ptrC{ ptrA };

	std::cout << "ptrA指针共有多少个指针调用:" << ptrA.use_count() << std::endl;

}

5)判断共享智能指针是否唯一(unique)

//判断共享智能指针是否唯一
bool std::shared_ptr.unique();
//unique()返回一个bool值,如果当前智能指针是唯一拥有该指针的,那么返回true,负责返回false
注:C++17标准无法使用该函数,只能在17之前使用
//unique()用法
#include <iostream>

int main()
{
	int* a{};
	std::shared_ptr<int>ptrA{ std::make_shared<int>(5) };
	std::cout << "判断指针指针ptrA是否唯一:" << ptrA.unique() << std::endl;
	std::shared_ptr<int>ptrB{ ptrA };       //共享ptrA的内存地址
	std::shared_ptr<int>ptrC{ ptrA };
	std::cout << "判断指针指针ptrA是否唯一:" << ptrA.unique() << std::endl;
}

4)共享智能指针的释放

​ reset()会将当前共享指针设置为nullptr,同时如果当前智能指针是最后一个拥有该指针的对象,那么将会释放内存。只有最后一个指针变量释放,才能释放内存空间

//共享智能指针的释放
std::shared_ptr.reset();
//reset()使用
#include <iostream>

int main()
{
	int* a{};
	std::shared_ptr<int>ptrA{ std::make_shared<int>(5) };
	std::shared_ptr<int>ptrB{ ptrA };       //共享ptrA的内存地址
	std::shared_ptr<int>ptrC{ ptrA };

	ptrB.reset();                   //只是修改指针的指向,并不释放指针内存地址
	std::cout << ptrB << std::endl;
	ptrA.reset();
	std::cout << ptrA << std::endl;
	std::cout << ptrC << std::endl;
	ptrC.reset();                  //释放智能指针的内存地址
	std::cout << ptrC << std::endl;
}

标签:std,ptrA,十三,int,引用,shared,unique,指针
From: https://www.cnblogs.com/piaolaipiaoqu/p/17850564.html

相关文章

  • C语言【指针1】
    C语言【指针1】1、指针类型长度随操作系统,64位操作系统为8Byte。​ 具体说一下:地址相当于门牌号,一般一个地址指向的空间是一个字节(下面按一个字节叙述,计算机底层也许也有按双字节编码的)。对于64位机器,某一个地址有64位,所以在空间里存那某一个地址时,这64位即8Byte。这64位总共能......
  • (二十三)C#编程基础复习——Struct结构体
    在C#中,结构体也称为结构类型("structuretype”或“structtype”),它是一种可封装数据和相关功能的值类型,在语法上结构体与类(class)非常相似,它们都可以用来封装数据,并且都可以包含成员属性和成员方法。一、定义结构体要定义一个结构体需要使用struct关键字,每个结构体都可以被看作......
  • 当项目中引用了 nuget 包,却在输出时无法找到对应文件时
    可以检查项目文件中对应包的属性是否有PrivateAssets=‘All’这个属性会在最终输出时,不复制相关文件,在nuget包仅在开发过程中使用时会比较有用。参考链接:https://learn.microsoft.com/zh-cn/nuget/consume-packages/package-references-in-project-files#controlling-depen......
  • 判断子序列(双指针)
    一、题目来源AcWing算法基础课-2816.判断子序列二、题目描述给定一个长度为\(n\)的整数序列\(a_1,a_2,…,a_n\)以及一个长度为\(m\)的整数序列\(b_1,b_2,…,b_m\)。请你判断\(a\)序列是否为\(b\)序列的子序列。子序列指序列的一部分项按原有次序排列而得的序列,......
  • 数组元素的目标和(双指针)
    一、题目来源AcWing算法基础课-800.数组元素的目标和二、题目描述给定两个升序排序的有序数组\(A\)和\(B\),以及一个目标值\(x\)。数组下标从\(0\)开始。请你求出满足\(A[i]+B[j]=x\)的数对\((i,j)\)。数据保证有唯一解。输入格式第一行包含三个整数\(n,m,......
  • 最长连续不重复子序列(双指针)
    一、算法描述含义双指针,指的是在遍历对象的过程中,不是普通的使用单个指针进行访问,而是使用两个相同方向(快慢指针)或者相反方向(对撞指针)的指针进行扫描,从而达到相应的目的。另外还可以根据序列进行区分,例如在快排中,双指针指向的是同一个序列,而归并排序中两个指针指向的是两个......
  • 汇编-PTR指针
            ......
  • 迅为RK3568开发板学习之Linux驱动篇第十三期输入子系统
    驱动视频全新升级,并持续更新~更全,思路更科学,入门更简单。迅为基于iTOP-RK3568开发板进行讲解,本次更新内容为第十三期,主要讲解输入子系统,共计24讲。关注B站:北京迅为电子,在线观看1.总领:本期视频介绍2.什么是输入子系统?3.如何确定输入设备与节点的对应关系?4.实践:确定输入设备对应的......
  • java向 jni传递问文件指针
    1、创建fd,jni接口publicstaticnativeintopenFileFromNative(FileDescriptorfileDescriptor);2、java文件获取文件指针ParcelFileDescriptorpfd==getContentResolver().openFileDescriptor(filePathUri,"rw");FileDescriptorfd=pfd.getFileDescriptor()......
  • AutoCAD(VBA)引用excel函数
    AutoCAD(VBA)要引用excel可以把它定义成为一个对象,进行引用。'CAD调用EXCEL程序PublicFunctionexcelActive()AsObjectDimxlappAsObjectSetxlapp=GetObject(,"Excel.application")SetexcelActive=xlapp.ActiveSheetEndFunction......