C++指针详解--完全零基础入门(从内存开始讲起)图文并茂

指针_Pointer

**

没有任何装逼的意思,我强烈建议大家VS和notepad一起使用。

**

小伙子,请问做程序员压力大吗?
在这里插入图片描述
写在最前面的两个知识点:
1. 首地址:一段内存空间中第一个存储单元的地址。存储单元。
2. 指针变量的加减:+ - ++ --。以指针指向的类型空间为单位进行偏移。

一、内存四区

  • 理解指针的工作原理以及使用指针操作数据,首先要理解计算机内存数据之间的工作原理。 C语言之所以效率高,就是因为C可以像汇编一样去操控内存。
    所以,也可以说,学C语言,学的就是内存。

1.1 粗浅理解内存

假设计算机的内存为图1.
在这里插入图片描述
如果我们定义一个整型变量a。int a = 5;那么,在计算机的从内存中,就会开辟出四个字节4B的空间。图中每个空格表示一个字节,红色部分表示一个int型变量所占的内存空间为4B。

  1. 栈区:系统自动开辟,自动释放;不死很大。
  2. 堆区:程序员手动开辟,手动释放,在C++中是,new delete。
  3. 全局区:全局静态变量。
  4. 代码区:保存代码。

什么叫自动开辟呢!
在这里插入图片描述
我们定义一个for循环:

int nain()
{
for(int i = 0; i<0;i++)
//函数体
cout << i <<endl;
return 0;
}

这个时候,这个i占据的空间就是程序自动开辟出来的变量空间,在该for循环运行结束后,会自动释放。
在这里插入图片描述该图片来自黑马老师视频

二、地址

  • 把内存以字节为单位进行编号,这个编号就是地址。并且是唯一的,如图2所示,我们可以把内存看成是一个由一个个1个字节的空间组成的“长”。而每个字节所在的空间(方格)都有一个编号,这个编号就是地址。如下面所示,假设第一个地址是1000,以此类推,这些编号都是连续的、唯一的。
  • 当然了,我们也可以这些内存理解成学校里的每间教室,而每个“方格”就是一个房间,每个房间都有一个门牌号,这个门牌号其实就是地址。比如,六号教学楼的六楼的6号房间,就是666。

在这里插入图片描述
地址是一种数据,
使用 &表示取址符,该符号返回一个变量的地址。
实例:

int main()
{
   int a=6;//定义一个整形变量。
   int * ptr_a = &a;//定义一个指向变量a的变量,该变量存储a的地址。
return 0;
}

  • 注意了,这个很重要》!!首地址:首地址是这个数据的 第一个存储单元 的地址。{后面细讲}

三、首地址

一段内存空间中第一个存储单元的地址。
在这里插入图片描述

  • 如图3所示,我们先定义一个整型变量a,inta;,该变量在内存空间中占据四个字节(4B),如图3中上半部分。则首地址就是1000,即一段内存空间中第一个存储单元的地址。

在这里插入图片描述

  • 这时,我们在定义一个一维数组inta[5];。那个这个数组由5个整型变量组成,因此占据了20个字节。其中第一维就占据了4个字节(这边一定要理解)。
  • 这个时候的首地址依然是1000,但是这个时候的1000就不是a[0]的第一个单元的地址了,而是a[0]的地址。
  • 到这边的时候大家可能都还不明白,还是稀里糊涂的。OK,没关系。
    在这里插入图片描述
    如图4所示:
    在这里插入图片描述
  • 这边大家都可能还会有点不明白,但是后面肯定就会懂了。多看几遍。这一章节的主要任务是大家要记住什么是首地址。

四、指针变量

到这里,我们才正式进入主题

  1. 用来存放地址的变量;
  2. 内存大小永远为4B。
    地址是一些编号,一种数据。
    变量有好多类型:
    整型变量:int a;
    字符型变量: char c;
    小数:float f;
    地址: 指针变量。
    总的来讲,指针变量是用来存放内存地址的变量。

4.1 指针变量的定义

 格式:数据类型 *变量名;

在这里插入图片描述

int main()
{
int a = 5;
int *p;//这是定义一个指针变量p,其中p中存的是地址。
//int则指明了这个指针中所保存的数据类型。
//*则指明了p是一个指针变量。
int *ptr_a = &a;
}

解释一下int *ptr_a = &a;//&表示取址符,获取变量a的地址。
这句话我们可以给写成下面两个语句的形式:
int *p;
p = &a;//理解成p指向a。
如图5所示,我们假设每个空格是4字节。
为什么我们说p指向a呢,因为p存储着变量a的地址。
在这里插入图片描述

4.2 指针变量的赋值

很简单,如下所示,完成赋值。
int *p;
p = &a;
我们的重点是如何访问每个变量

4.3 指针变量的引用

访问a这个变量。

  • 方法一:直接使用下标法。
 int main()
{
 int a[5] = {1,2,3,4,5} ;
for(int I = 0;i<5;i++)
{
//打印出每个变量
cout <<a[i] <<,;
}
cout << endl;
}

  • 方法二:使用变量名访问。
int main()
{
int a = 5;
cout <<”a =<< a <<endl;
}

  • 方法三:使用指针访问
    用p指向的内存中的值。
    用指针访问变量的值的方法:*指针变量(即:*p)
int main()
{
int a = 8;
int *p;
p = &a;
cout << “使用指针p=<< *p<<endl;
}

这边需要注意:关于指针的*的两种情况:

  1. 当使用 ∗ * 去访问变量的值时,即 *p,此时的 ∗ * 表的是取值运算符,返回的是某一个地址中的值。参见上述公式第4行.
  2. 当在定义指针变量的时候,即int ∗ p _{}^{*}\textrm{p} p,此时的 ∗ * 只是表示定义这个p为一个指针。此时的a和 ∗ p _{}^{*}\textrm{p} p是一个概念,因为 ∗ p _{}^{*}\textrm{p} p是指向a的。参见上述公式第6行。
int main()
{
	//验证*号的用法
	int a = 5 ;
	int *p ;
	p = &a;
	int *p_a = &a;
	cout << "取地址  p:" << p << endl;
	cout << "取地址p_a:" << p_a << endl;
	//如果想获取地址所存储的变量,则需要加上*号
	cout << "取数值  p:" << *p << endl;
	cout << "取数值p_a:" << *p_a << endl;
}

在这里插入图片描述
这边结合图5一下子就明白啦
在这里插入图片描述

  1. 野指针:

不能明确指向的指针变量,这种指针很危险的。
举个例子:小时候会有人说野孩子,什么是野孩子?就是找不到父母,没有父母的流浪孩子。这个野指针也是这样,野指针不知道自己具体指向哪个变量,以后你调用这个野指针的时候,会非常危险,因为你不知道他返回的是什么样的值。
来个代码说明一下:
先来个简单的,

int main()
{
int a;
cout<< a<<endl;
return 0;
}

这个时候,你打印这个变量,绝对编译器会报错,不信你可以试试。
同样,对于野指针也是这样:

int main()
{
int  a = 5;
int *p;
cout<< a<<endl;
cout<< p<<endl;
return 0;
}

此时,p离面保存的地址是不确定的,p的指向是不明确的。
危险,危险,危险……
比如说,这个指针指向的是sudo rm –rf,那就惨啦。不懂的就去百度sudo rm –rf的意思啦。
在这里插入图片描述

  • 肯定有解决方案:

在定义这个指针的时候,如果你暂时用不到它,就把他弄成一个空指针。
int *p = NULL;
下面开始讲空指针啦

  • 空指针:
  • 指针有如下几种类型:int* float* char* double ∗ ^{*} 等类型的指针,而定义空指针则使用:void ∗ ^{*} 。也就是说这样的一个指针不知道指向一个什么样类型的内存(这个比野指针还恶心好像)。
  • 简单解释一下,假如我在内存中开辟了一个4B的内存空间,这4B的空间可以存放int ∗ ^{*} 型,long ∗ ^{*} 型,float ∗ ^{*} 型。在我还不知道这个内存到底存什么类型的变量的时候,我可以先用void*开辟一个空间。然后再需要使用的时候强制转换一下。强制转换后面讲好不好。

4.4 指针变量的运算

严格来讲,指针的运算只有下面四个:
+ - ++ –
有哪些没意义的地址运算操作:

  1. 两个地址相加,例如:北京路1号+南京路1号。没有任何意义
  2. 两个地址相乘或一个地址乘以或者除一个常数,例如:北京路1号*3,没有任何意义

什么是有意义的呢?
指针的偏移,即指针的运算就是地址的偏移。如图6所示。
在这里插入图片描述
注意啦!!下面是关键。

在这里插入图片描述
一). 指针变量的加减,以指针所指向的类型空间为单位进行偏移。我们上面图6的例子是默认该指针所指向的类型空间是1B,依次每次+1指针都偏移一个字节。
二). 因为我们可以定义不同类型的指针:
char *p; // 1B 指针+1一次,指针偏移1个字节
int *p;// 4B 指针+1一次,指针偏移4个字节
double *p;// 8B 指针+1一次,指针偏移8个字节

当然了,也不是说只能+1 还可以+2 +3 ………
-----------------------------------------------------在这里插入图片描述

int main
{
	int a;
	int * p_a = &a;
	double b;
	double *p_b = &b;
	cout << "int型变量站4个字节" << endl;
	cout << "  p_a=" << p_a<<endl;;
	cout << "p_a+1=" << p_a+1<< endl;
	cout << "p_a+2=" << p_a + 2 << endl;
	cout << "double型变量站8个字节" << endl;
	cout << "  p_b=" << p_b << endl;
	cout << "p_b+1=" << p_b+1 << endl;
cout << "p_b+2=" << p_b + 2 << endl;
return 0;
}

上述代码在我的电脑上的截图,每次运行,每个人的电脑结果是不一样的。但是偏移量是一样的。
在这里插入图片描述

  • 上述是16进制计算的,大家看的时候要注意点。Int型每次偏移4个,+2的时候就偏移八个字节。
  • double型占8个字节,每次偏移8个字节,+2的时候就偏移16个字节。大家算一下就知道了。
    三). 强调开头的那两个知识点了。

在这里插入图片描述
1) 首地址:一段内存空间中,第一个存储单元的地址。存储单元。
2) 指针变量的加减,以指针所指向的类型空间为单位进行偏移。

五、一维数组与指针

当我们去定义一个数组,这个数组里面的元素是连续存放的。数组名是这个数组的《首地址》。

在这里插入图片描述

int main()
{
int x[5], i;
	for (i = 0; i < sizeof(x); i++)
		printf("00%x\n", ((char*)(&x)) + i);
		cout << "数组名x地址:"<< x <<endl;
	cout << " 寻址&x地址:" << &x << endl;
return 0;
}

在这里插入图片描述
看,截图是我的运行结果。数组名x的地址就是第一个变量的地址,即首地址。而寻址&x获取的值也是第一个变量的地址,即首地址。

在这里插入图片描述
对,大家都发现了。
在这里插入图片描述

  • 这两个东西是一样的。但是,他们所指向的类型空间不一样(看到没有,这边是上面的第二句话)。下面我来证明一下他们来的类型空间不一样。这个关键哦,学会了就懂得如何操作指针的第一步了。
    在这里插入图片描述
int main()
{
	int b[5];
	int *ptr_b = &b[5];
	cout <<"      b="<< b << endl;//b这个地址指向b[0]这个元素,因为是整型,因此占4个字节。
	cout<<"     &b=" << &b << endl;//&b指向的是整个数组,整个数组有5个int型的元素,因此有每当&b+1时,指针移动的是5*4 = 20 个字节。
	cout << "  ptr_b=" << ptr_b << endl;
	//所以有结论,指针变量的加减,以指针指向的类型空间为单位进行偏移。
	cout << "    b+1=" << b+1 << endl;
	cout << "   &b+1=" << &b+1 << endl;
cout << "ptr_b+1=" << ptr_b+1 << endl;
return 0;
}

在这里插入图片描述
这个图是上面的一次运行结果。分析结果都在代码的注释里面了。

在这里插入图片描述
总结一下:

  1. a这个地址指向的是a[0]这个int元素,他的类型是:int*,4个字节 。
  2. &a这个地址指向整个数组元素,它的类型是:int(*)[5];

这边大家后面进阶部分会可以理解,或者百度其他坐着的连接。

5.2 访问数组元素

  1. 下标法:这个很简单啦,学过matlab和python的小伙伴应该很喜欢的。
int main()
{
	int a[5] = { 1,2,3,4,5 };
	for (int i = 0; i < sizeof(a) / sizeof(int); i++)
	{
		cout << a[i] << ", " ;
	}
	cout << endl;
return 0;
}

  1. 指针法:

下面就有意思啦。
在这里插入图片描述

int main()
{
	int a[5] = { 1,2,3,4,5 };
	int *p_a = a;//p_a指向a[0]
	cout << *p_a << endl;
	for (int i = 0; i < sizeof(a) / sizeof(int); i++)
	{
		cout << "a[" << i << "]=" << *p_a + i << endl;//或者*(p_a + i),都可以。
}
Return 0;
}

这边大家结合着这句话理解呀!

  1. 当使用 ∗ * 去访问变量的值时,即 ∗ p _{}^{*}\textrm{p} p,此时得 ∗ * 表的是取值运算符,返回的是某一个地址中的值。
  2. 当在定义指针变量的时候,即int ∗ p _{}^{*}\textrm{p} p,此时的 ∗ * 只是表示定义这个p为一个指针。此时的a和 ∗ p _{}^{*}\textrm{p} p是一个概念,因为 ∗ p _{}^{*}\textrm{p} p是指向a的。
    在这里插入图片描述
int main()
{
	int a[5] = { 1,2,3,4,5 };
	int *p_a = a;//p_a指向a[0]
	cout << *p_a << endl;
	for (int i = 0; i < sizeof(a) / sizeof(int); i++)
	{
		cout << "a[" << i << "]=" << *p_a++ << endl;
	}
return 0;
}

在这里插入图片描述
小小的分析一下:

  1. *(p+1):进行运算的时候,p是不会发生变化的
  2. *p++:进行运算的时候,p是一直在偏移的。

我们说了,a是数组的第一个元素的地址,它指向a[0]。我们也定义了一个 ∗ p _{}^{*}\textrm{p} p = a;这个 ∗ p _{}^{*}\textrm{p} p也指向a[0]。

六、二维及以上数组与指针操作

6.1 二维及以上数组的存储特性

  • 首先,我要先把你们的思想掰直了。特别是那些先matlab和python的非计算机专业的同学,尤其是先学matlab的同学非计算机专业的同学。你们可要注意了:看图7
    在这里插入图片描述图7

虽然我们经常会说一个矩阵式m行n列,但是在计算机中不是这样存储的,而是就把他存储成一行。至于我们在matlab中看到的,那些都是经过内部代码处理的,最核心部分其实是还是指针,只是开发人员将它们封装起来了。

我们举个例子,首先,我们定义一个3行4列的矩阵。虽然我们平时说他是三行四列,但是在计算机中,其实就是一行的连续存储方式,如图8所示。像我们在数学书上看到的那种正方形的形式,是根本不存在的。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

int main()
{
	//二维数组部分
	int a[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
	//虽然我们定义的这个a是一个3行4列的,但是,在我们的计算机存储中,他已然是连续存储的。
	cout << "a[0]=" << a[0] << endl;
	cout << "a[1]=" << a[1] << endl;
	cout << "a[2]=" << a[2] << endl;
}

在这里插入图片描述

  • 这边,其实a[0]表示第0行,其实a[1]表示第1行,其实a[2]表示第2行。因为每行有4个元素,每个元素占4B;上面的代码显示的指针偏移正好每个偏移16位,而代码的进制也正好是16进制的。
  • 这也验证了我们上面的话:“a是数组的第一个元素的地址”。我们将上述代码扩充,显示每个地址和每个地址对应的元素。
    在这里插入图片描述
int main()
{
	//二维数组部分
	int a[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
	int i;
	//虽然我们定义的这个a是一个3行4列的,但是,在我们的计算机存储中,他已然是连续存储的。
	cout << "a[0]=" << a[0] << endl;
	cout << "a[1]=" << a[1] << endl;
	cout << "a[2]=" << a[2] << endl;
	for ( i = 0; i < sizeof(a); i++)
	{
		//printf("0%x\n", &a+ i);
		cout<< &a + i << endl;
	}
	cout << "a[1][0]=" <<a[1][0] << endl;
}

  1. 但是如果想显示a[0] a[1] a[2]所对应的元素,还是需要调用指针的,这时候其实就能看出来,计算机存储是一个连续的了,而不是几行几列的那种。
  2. Note that:地址是一直在变的。为什么在变呢,因为计算机的运行内存你就那么点,16G,32G。。。。。看你插几个内存条了。这么点内存,肯定是用的时候开辟,不用的时候就是释放掉。
    下面就小小的总结一下上面要表达的东西。
  3. 数组名:a。a是数组a[3][4]的首地址。首地址????大家应该知道了吧。a的类型是:int( ∗ ^{*} )[4];所以,a+1,加一次就偏移16个字节。a[0]是这个一维数组的数组名,a[0]指向a[0]
    [0],这边为什么说指向a[0] [0],大家看上面的地址就知道了。所以a[0]
    的类型是:int ∗ ^{*} ,每次加4个字节。而&a的类型是:int ∗ ^{*} [3][4],所以它是指向整个数组的。所以&a+1;则跳过48B。
    a指向数组的第一个存储单元,第一个存储单元就是这个数组的第一个一维数组。一个二维数组的存储单元就是一个个的一维数组。因此,我们可以引申出,一个三维数组a[2][3][4],那么,我们先把这个数组先拆成两个二维数组,然后,再把这两个二维数组分别拆成三个一维数组,再把这每个一维数组拆成四个元素。所以,这个数组我们可以将其看成是一个由两个3*4的矩阵组成的数据。那个,三维数组的第一个存储单元就是一个二维数组。以此类推,到高维数组。

在这里插入图片描述

int main()
{
	//二维数组部分
	int a[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
	int i;
	//虽然我们定义的这个a是一个3行4列的,但是,在我们的计算机存储中,他依然是连续存储的。
	cout << "a[0]=" << a[0] << endl;
	cout << "a[1]=" << a[1] << endl;
	cout << "a[2]=" << a[2] << endl;
	for ( i = 0; i < sizeof(a); i++)
	{
		//printf("0%x\n", &a+ i);
		cout<< &a + i << endl;
	}
	cout << "a[1][0]=" <<a[1][0] << endl;
	cout << "a指向数组的第一个存储单元:" << a << endl;
}

好,下面来个震撼的,大家就可以一目了然了。我们定义一个八维数组
int a[2][3][4][5][6][7][8][9];
则:a是数组名。

  1. a指向7维数组
  2. a[0]指向6维数组
  3. a[0][0]指向5维数组
  4. a[0][0][0]指向4维数组。
  5. ……
  • 理解了这些东西有什么用? 对了,就是访问数组。

6.2 二维及以上数组元素的访问

在5.2小节中,我们学习了一维数组的访问,分别有下表法和指针法。

6.2.1 下标法

下标法我们就不介绍了。直接给个代码吧
在这里插入图片描述

int main()
{

	//下标法在二维数组中的应用
	int a[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
	//简单调用
	cout << "简单访问" << endl;
	cout << "a[0][0] = " << a[0][0] << endl;
	cout << "a[0][3] = " << a[0][3] << endl;
	cout << "a[1][0] = " << a[1][0] << endl;
	cout << "a[1][3] = " << a[1][3] << endl;
	//for循环调用
	cout << "for循环访问" << endl;
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 4; j++)
		{
			cout << "a[" << i << "][" << j << "] = " << a[i][j] << endl;
		}
	}
return 0;
}

  • 下标法没什么好讲的。大家都懂的,特别是学过matlab的同学,什么切片什么的,matlab里面用的贼方便。

6.2.2 指针法

先看图。如图9所示。同样是针对那个数组:int a[2][3][4][5][6][7][8][9];

在这里插入图片描述

  • 我要根据指针操作,找到m行的第n个元素。首先找到这一行的首地址,然后再对该指针进行加操作,实现指针的偏移。如图9所示,如果我们想要访问图中三角形所示的元素,我们首先要找到该维数组的首地址,然后+2。
  • 即a[m]+m。
  • 不多说,直接上代码
int main()
{
	//用指针访问二维数组。
	int a[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
	int *ptr_a;
	//简单访问元素
	cout <<"访问第二行第三列的元素7: "<< *a[1] + 2 << endl;
	cout << "访问第三行第二列的元素10: " << *a[2] + 1 << endl;
	//使用for循环访问
	cout << "用指针访问" << endl;
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 4; j++)
		{
			cout  << *a[i]+j <<"  ";
		}
		cout<<endl;
	}
return 0;
}

下一章可能会是引用把
有错误的请指正,微信:shuoshi6666.欢迎讨论。

  • 9
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
C++智能指针 智能指针_unique_ptr智能指针详解 智能指针详解 作为智能指针的⼀种,unique_ptr 指针⾃然也具备"在适当时机⾃动释放堆内存空间"的能⼒。和 shared_ptr 指针最⼤的不同之处在 于,unique_ptr 指针指向的堆内存⽆法同其它 unique_ptr 共享,也就是说,每个 unique_ptr 指针都独⾃拥有对其所指堆内存空间的所有 权。 这也就意味着,每个 unique_ptr 指针指向的堆内存空间的引⽤计数,都只能为 1,⼀旦该 unique_ptr 指针放弃对所指堆内存空 间的所有权,则该空间会被⽴即释放回收。 unique_ptr 智能指针是以模板类的形式提供的,unique_ptr<T>(T 为指针所指数据的类型)定义在<memory>头⽂件,并位于 std 命名空间 中。因此,要想使⽤ unique_ptr 类型指针,程序中应⾸先包含如下 2 条语句: 1. #include <memory> 2. using namespace std; 第 2 句并不是必须的,可以不添加,则后续在使⽤ unique_ptr 指针时,必须标注std:: 。 unique_ptr智能指针的创建 智能指针的创建 考虑到不同实际场景的需要,unique_ptr<T> 模板类提供了多个实⽤的构造函数,这⾥给读者列举了⼏种常⽤的构造 unique_ptr 智能指针的⽅式。 1) 通过以下 2 种⽅式,可以创建出空的 unique_ptr 指针: 1. std::unique_ptr<int> p1(); 2. std::unique_ptr<int> p2(nullptr); 2) 创建 unique_ptr 指针的同时,也可以明确其指向。例如: 1. std::unique_ptr<int> p3(new int); 由此就创建出了⼀个 p3 智能指针,其指向的是可容纳 1 个整数的堆存储空间。 和可以⽤ make_shared<T>() 模板函数初始化 shared_ptr 指针不同,C++11 标准中并没有为 unique_ptr 类型指针添 加类似的模板函数。 3) 基于 unique_ptr 类型指针不共享各⾃拥有的堆内存,因此 C++11 标准中的 unique_ptr 模板类没有提供拷贝构造函数,只提供 了移动构造函数。例如: 1. std::unique_ptr<int> p4(new int); 2. std::unique_ptr<int> p5(p4);//错误,堆内存不共享 3. std::unique_ptr<int> p5(std::move(p4));//正确,调⽤移动构造函数 值得⼀提的是,对于调⽤移动构造函数的 p4 和 p5 来说,p5 将获取 p4 所指堆空间的所有权,⽽ p4 将变成空指针(nullptr)。 4) 默认情况下,unique_ptr 指针采⽤ std::default_delete<T> ⽅法释放堆内存。当然,我们也可以⾃定义符合实际场景的释放规 则。值得⼀提的是,和 shared_ptr 指针不同,为 unique_ptr ⾃定义释放规则,只能采⽤函数对象的⽅式。例如: 1. //⾃定义的释放规则 2. struct myDel 3. { 4. void operator()(int *p) { 5. delete p; 6. } 7. }; 8. std::unique_ptr<int, myDel> p6(new int); 9. //std::unique_ptr<int, myDel> p6(new int, myDel()); unique_ptr<T>模板类提供的成员⽅法 模板类提供的成员⽅法 为了⽅便⽤户使⽤ unique_ptr 智能指针,unique_ptr<T> 模板类还提供有⼀些实⽤的成员⽅法,它们各⾃的功能如表 1 所⽰。 表 1 unique_ptr指针可调⽤的成员函数 成员函数名 成员函数名 功 功 能 能 operator*() 获取当前 unique_ptr 指针指向的数据。 operator->() 重载 -> 号,当智能指针指向的数据类型为⾃定义的结构体时,通过 -> 运算符可以获取其内部的指定成员。 operator =() 重载了 = 赋值号,从⽽可以将 nullptr 或者⼀个右值 unique_ptr 指针直接赋值给当前同类型的 unique_ptr 指针。 operator []() 重载了 [] 运算符,当 unique_ptr 指针指向⼀个数组时,可以直接通过 [] 获取指定下标位置处的数据。 get() 获取当前 unique_ptr 指针内部包含的普通指针。 get_deleter()

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值