栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

c++11 智能指针

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

c++11 智能指针

c++11 智能指针

c++中时常发生内存泄漏问题,在c++98中引入了auto_ptr指针,然而在c++11中已经摒弃了auto_ptr,新引入了三种智能指针模板(shared_ptr、unique_ptr、weak_ptr)。

首先我们需要了解内存是如何分配的?

void demo1()
{
	int * pd = new int;
	*pd = 10;
	return;
}

demo1中,未使用任何智能指针。变量的分配步骤为三步,如此pd的内存并没有被释放。

  1. 为pd和一个int值分配存储空间
  2. 将值复制到动态内存中
  3. 删除pd,值保留在了动态内存中
void demo2()
{
	auto_ptr pd(new int);
	*pd = 10;
	return;
}

demo2中,内存的分配虽然也分为了三步,但是auto_ptr自带的析构函数会将内存释放。具体如下

  1. 为pd和一个int值分配存储空间
  2. 将值复制到动态内存中
  3. 删除pd,pd的析构函数释放动态内存。

那么既然已经有auto_ptr智能指针了,为什么还要引入新指针了,接下来的demo将会解开这个问题

void demo3()
{
	auto_ptr a(new int(5));
	auto_ptr b;
	b = a;

	cout << *a << endl;//Error:a已经将此块内存地址所有权转让给b
}

如果a和b是常规指针,那么两个指针指向同一块内存地址,在出作用域范围时,程序试图将内存释放两次,这样一来程序就会抛出异常。要避免这种问题,有以下几种解决方案

  • 定义赋值运算符,执行深复制,使一个对象成为另一个对象的副本。存在于不同的内存空间中。
  • 创建更高级指针,使用引用计数,计数为0时清空内存,避免同一内存块多次释放

auto_ptr 和 unique_ptr的区别
依旧是上面的demo3,使用auto_ptr 将会在程序运行时出错,而当使用unique_ptr时,程序在编译阶段直接报错!如果unique想使用所有权传递,那么使用std::move函数

void demo3()
{
	unique_ptr a(new int(5));
	unique_ptr b = a;//Error
	unique_ptr b = move(a);//Correct

	cout << *b << endl;
}

Unique_ptr:release()函数,将原本绑定的独占式指针和对象进行分离,利用其它指针接收对象,独占式指针自动销毁

void demo4()
{
	unique_ptr a(new int(5));
	
	int* c = a.release();
	cout << *c << endl;
}

shared_ptr:引入了引用计数器,计数器归0,直接销毁对象

use_count计数,计算的是指向这个对象的个数,即指向该变量的地址,而不是这个指针被操作了多少次。


很显然,计数只针对于share_ptr,对于普通指针不进行计数

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/433315.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号