C++11之--智能指针

       C++11标准库提供了两种智能指针(smart pointer)类型来管理动态对象。智能指针的行为类似常规指针,重要的区别是它负责自动释放所指的对象。C++11标准库提供的这两种智能指针的区别在于管理底层指针的方式:shared_ptr允许多个指针指向同一个对象;unique_ptr则"独占"所指向的对象。C++11标准库还定义了一个名为weak_ptr的辅助类,它是一种弱引用,指向shared_ptr所管理的对象。这三种类型都定义在memory头文件中。智能指针是模板类而不是指针。类似vector,智能指针也是模板,当创建一个智能指针时,必须提供额外的信息即指针可以指向的类型。默认初始化的智能指针中保存着一个空指针。智能指针的使用方式与普通指针类似。解引用一个智能指针返回它指向的对象。如果在一个条件判断中使用智能指针,效果就是检测它是否为空。

1、shared_ptr智能指针内存管理的思路

shared_ptr智能指针的解决思路:最后一个引用它的对象被释放时,释放这段内存。

实现方法:对 被管理的资源 进行计数。当一个sharedptr对象要共享这个资源的时候,该资源的引用计数加1,当该对象生命周期结束了,再把该引用计数减1。这样,当最后一个引用它的对象被释放的时候,资源的引用计数减少到0,此时释放该资源。

 

智能指针最终的实现是 两个指针成员:一个指向数据成员,一个指向计数器成员

智能指针里的计数器 维护的是一个指针,指向的 实际内存 在堆上,不是栈上的

 

make_shared类似于emplace_back()它是一种更好且更安全的方法:因为使用new时会创建一个对象,计算它的引用计数时会创建一个对象,而make_shared只会创建一个对象,并且不会出现控制模块失效的情况。make_shared返回指向此对象的shared_ptr

2、weak_ptr

weak_ptr<T>w

weak_ptr<T>w(sp)

w = p               p可以是一个shared_ptr或一个weak_ptr赋值后wp共享对象

w.reset()          将w置空

w.use_count() 与w共享的shared_ptr的数量

w.expired()      若w.use_count()为0,返回true,否则返回false

w.lock()            若expired为true,返回一个空shared_ptr;否则返回一个指向w的对象的shared_ptr(也就是说对象不为空)

 

auto p = make_shared<int>(41);

weak_ptr<int> wp(p);

weak_ptr是弱指针,由于是弱共享创建wp不会改变p的引用计数;(相当于一个小弟)wp指向的对象(大哥shared_ptr的对象)

可能 被释放掉。所以不能用weak_ptr直接访问对象,需要使用lock,对象被释放返回一个空shared_ptr,对象不为空返回一个指向w的对象的shared_ptr

 

3、shared_ptr

shared_ptr<T> p(q)

shared_ptr<T>p(u)

p = q        p和q都是shared_ptr,所保存的指针必须能相互交换,此操作会递减p的引用计数,递增q的引用计数,若p的引用计数变为0,则将其管理的原内存释放

p.unique 若p.use_count()为1,返回true,否则返回false

p.use_count()返回与p共享的智能指针数量,可能很慢主要用于调试

 

4、unique_ptr

unique_ptr没有类似make_shared的标准库函数,必须unique_ptr<int>p(new int(10)),不支持赋值和拷贝

unique_ptr<string>p1(new string("aaa"))

unique_ptr<string>p2(p1);不支持拷贝所以不对(有点类似拷贝构造函数   Complex c2(c1);     Complex c2 = c1;//这个是初始化不是赋值)

unique_ptr<string>p3

p3 =p2 不支持赋值所以不对

unique_ptr<string>u;

u = nullptr 释放u指向的对象,将u置空

u.release()  u放弃对指针的控制权,返回指针并将u置为空

u.reset() 释放u指向的对象  //释放对象,同时赋空

u.reset(q)如果提供了内置指针q,令u指向这个对象,否则将u置空

unique_ptr<string>不支持普通的拷贝和赋值操作,但是可以通过release or reset来转移所有权。

p2.reset(p3.release())将所有权从p3转移给p2,reset释放了原来的内存或者使用move

 

auto px = p.release(); //让出指针所有权,但是并没有销毁

 delete px; //这里需要手动delete px

#include <iostream>
#include <string>
#include <memory>
using namespace std;

 void main()
{
	shared_ptr<string>p1(new string("aaa"));
	shared_ptr<string>p2 = make_shared<string>(10,'9');
	shared_ptr<int>p3 = make_shared<int>();
	auto p4 = make_shared<string>(10,'9');
	cout << *p1 << endl;
	cout << *p2 << endl;
	cout << *p3 << endl;
	cout << *p4 << endl;

	auto q = make_shared<int>(10);
	weak_ptr<int> wp(q);//弱共享wp不会改变q的引用计数
	cout << "wp.use_count(): " << wp.use_count() << endl;//弱引用计算共享对象shared_ptr的数量
	if(!wp.expired())
	{
		cout << "wp.expire(): " << "false" << endl;
	}else{
		cout << "wp.expire(): " << "true" << "已删除delete" << endl;//use_count()=0返回true
	}
	auto ret = wp.lock();
	if(ret)
	{
		cout << "wp.lock(): " << "false" << *ret << endl;//不为空返回一个指向wp对象的shared_ptr
	}

	unique_ptr<string> p5(new string("uuuuuuuuuu"));
	cout << *p5 << endl;
	unique_ptr<string> p6(p5.release());
	unique_ptr<string> p7(new string("uuuuuuuuuu"));
	p6.reset(p7.release());
	cout << *p6 << endl;
 }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值