C++ 智能指针

举报
看,未来 发表于 2020/12/30 01:29:18 2020/12/30
【摘要】 什么是智能指针? 今天之前我对这个概念也很陌生,但是接触之后我便很喜欢这种指针了。 与其说是指针,不如说是一种基于指针的模板类。 智能指针存在的意义? 俗话说存在即合理,那么这个模板存在的意义是什么? 先看个简单的小栗子: void testA() { a = new testB(); ··· return; } 123456 短短几行,其实问题是很明显...
什么是智能指针?

今天之前我对这个概念也很陌生,但是接触之后我便很喜欢这种指针了。
与其说是指针,不如说是一种基于指针的模板类。

智能指针存在的意义?

俗话说存在即合理,那么这个模板存在的意义是什么?
先看个简单的小栗子:

void testA()
{
	a = new testB();
	···
	return;
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

短短几行,其实问题是很明显的,不过看不出来也正常,因为对大部分功力跟我差不多薄弱的人来说,那个不是错哈。

有没有发现这里只有new,并没有delete。每次调用,该函数都会从堆中申请内存,但是从来没有将内存释放。这样就会导致内存越用越多。
以前我是觉得有没有delete不重要,后来我知道必须要delete了,但是会忘记啊。。。

如果有人觉得为什么会忘记?好,不会忘,那我们再看个小栗子:

	a = new testB();
	···
	if(testC())
	{
		printf("TestC failed \n");
		perror("TestC:");
	}
	···
	delete a;
	return;

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

好,现在记得delete了,那还没来得及delete呢?异常了。

这时候就需要一套智能指针模板,不论发生什么情况,反正它记得自己去delete就好。

这正是auto_ptr、unique_ptr和shared_ptr背后的故事。


这三个指针模板都定义了类似指针的对象,可以将new(直接或间接)的地址赋给这种对象,当智能指针过期时,其析构函数将使用delete来释放内存。

来张图看的比较直观:
在这里插入图片描述

上面是auto_ptr的示例,另外两个也是一样的。


那怎么用呢?

要创建智能指针对象,首先要包它们的头文件memory.

然后看一下代码格式:

#include<memory>
//原:
string *ptr = new string;

//改
std::auto_ptr<std::string> ptr(new string);

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

另外两个也是这种格式

注意到这些模板是位于名空间std中的。

所有智能指针类都有一个explicit构造函数,所以不应该直接对这些指针类执行复制赋值,如下:

shared_ptr<double> pd;
double *pdd = new double;
pd = pdd;	//这个是不允许的
pd = shared_ptr<double> (pdd);	//上面那个改成这样

shared_ptr<double> ps = pdd;	//这样也是不允许的
shared_ptr<double> ps(pss);	//上面那个改成这样

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

接下来来看一个三种模板都应该避免的情况,其实前面的篇章也讲过了,就是将局部变量的地址传入堆区。

string str;
shared_ptr<string> sstr(&str);

  
 
  • 1
  • 2

这是明显错误的,该函数结束的时候,作为局部变量的str会被释放,但是sstr不会。


有关智能指针的注意事项:

  1. List item

首先,我们把auto_ptr摈弃掉。
因为它比较老,允许多个指针指向同一个变量。
那么回收的时候就会出现一个问题:一个变量被回收了多次。
那肯定是不允许的。

shared_ptr通过技术手段解决了这个析构的问题,unique_ptr则不允许将多个指针指向一个变量,它会在编译的时候直接报错。

  1. List item

相比另外两种模板,unique还有一种支持数组指针的变体。

std::unique_ptr<double[]> dbo(new double[5]);

  
 
  • 1
  1. List item

综上分析可得,shared_ptr支持指针数组,unique_ptr支持数组指针。

  1. List item
    不要将 *this指针交给智能指针。

  2. List item
    不要在函数实参中创建shared_ptr
    function (shared_ptr (new int),g());//有缺陷
    正确的写法应该是先创建智能指针: shared_ptr p(new int()); f(p,g());


什么时候释放智能指针?

这应该也是比较关心的问题吧。

指针的作用域结束时它就自己清理了。至于如果有人非要手动去释放,那我个人建议你用普通指针。

文章来源: lion-wu.blog.csdn.net,作者:看,未来,版权归原作者所有,如需转载,请联系作者。

原文链接:lion-wu.blog.csdn.net/article/details/105349931

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。