【C/C++】【智能指针】weak_ptr

weak_ptr

weak_ptr概述: 用来辅助shared_ptr进行工作
week 弱 弱共享 弱引用 共享其他shared_ptr所指向的对象
强指针指的是 shared_ptr  弱指针指的是 weak_ptr 
weak_ptr 也是类模板,也是智能指针,这个智能指针用来指向一个shared_ptr管理的对象

1) weak_ptr 不控制所指对象的声明周期,即将weak_ptr绑定到shared_ptr并不会改变shared_ptr的引用计数
   更确切的说weak_ptr的构造和析构不会增加或者减少所指向对象的引用计数

2) 当shared_ptr需要释放所指向的对象的时候可以照常释放,不管是否有weak_ptr指向该对象

3) weak_ptr的作用:可以理解成监视shared_ptr (强引用)的声明周期用的,是一种shared_ptr的扩充
    weak_ptr不是一种独立的智能指针,不能用来操作所指向的资源,看起来像是shared_ptr的助手
	weak_ptr能监视到它所指向的对象是否存在

weak_ptr的创建

//weak_ptr的创建
void func1()
{
    //创建weak_ptr的时候,一般是用一个shared_ptr来初始化
    auto pi = make_shared<int>(100); //shared_ptr

    //pi引用计数(强引用计数)不改变,但是弱引用计数会改变(弱引用计数会从0变成1)
    //强引用计数才能决定对象的声明期,弱引用计数对对象声明周期没有影响
    weak_ptr<int> piweak(pi); //piweak弱共享pi


    //另一种初始化
    weak_ptr<int> piweak1; //piweak弱共享pi
    piweak1 = pi; //把weak_ptr赋值给另外一个weak_ptr,现在pi是一个强引用,piweak和piweak1是两个弱引用



    //lock(): 功能就是检查weak_ptr所指向的对象是否存在
    //存在:lock就能返回一个指向该对象的shared_ptr, 指向的shared_ptrd的引用计数 + 1

    //auto pi2 = piweak.lock(); //pi2也是一个强引用
    //if (pi2) cout << " exists " << endl;

    //不存在:lock会返回一个空的shared_ptr
    pi.reset();
    auto pi3 = piweak.lock(); //pi2也是一个强引用
    if (pi3) cout << " exists " << endl;
    else cout << "not exists " << endl;

    //总结:weak_ptr能够判断所指向的对象是否存在
}

weak_ptr常用操作

/*weak_ptr常用操作*/
namespace _weak_ptr_op_
{
	//1. user_count():获取与该弱指针共享对象的其他shared_ptr的数量,或者获取当前观测资源的强引用计数
	void func1()
	{
		auto pi = make_shared<int>(100);
		auto pi2(pi);
		weak_ptr<int> p(pi);
		cout << pi.use_count() << endl;
	}

	//2. expired() 是否过期的意思,若该指针的use_count为0(表示该弱指针所指向的对象不存在了),返回true
	// 判断所观测的资源是否已被释放
	void func2()
	{
		auto pi = make_shared<int>(100);
		auto pi2(pi);
		weak_ptr<int> p(pi);
		cout << pi.use_count() << endl;
		pi.reset();
		pi2.reset();
		if (p.expired()) cout << "weak_ptr过期" << endl;
	}

	//3. reset():将该弱引用指针设置为空,不影响该对象的强引用数量,但是指向该对象的弱引用会减少1
	void func3()
	{
		auto pi = make_shared<int>(100);
		auto pi2(pi);
		weak_ptr<int> p(pi);
		p.reset(); //pi没有弱引用了
	}

	//4. lock()
	void func4()
	{
		auto p1 = make_shared<int>(42);
		weak_ptr<int> p2(p1);
		if (!p2.expired())
		{
			auto p3 = p2.lock(); //返回一个shared_ptr,并且此时强引用计数为2
			if (p3) cout << *p3 << endl;
			//离开这个范围,强引用计数会恢复为1
 		}
		else
		{
			int test;
			test = 1;
			//强引用计数为1
		}
	}
}

尺寸问题

/*
weak_ptr的尺寸和shared_ptr尺寸一样大,是裸指针的2倍
*/
void func()
{
    weak_ptr<int> pw;
    int* p;
    int pw_len = sizeof(pw); //8个字节 内部有两个指针,一个指向对象类型的指针,一个指向控制块的指针
    int p_len = sizeof(p); //4个字节


    //第一个裸指针指向的是这个智能指针所指向的对象
    auto p1 = make_shared<int>(42);
    weak_ptr<int> p2(p1);

    //第二个裸指针指向一个很大的数据结构(控制块)这个控制块中有
    // 1. 所指对象的强引用计数
    // 2. 所指对象的弱引用计数
    // 3. 其他数据,自定义的删除器的指针等等。

}

posted @ 2020-07-20 22:36  NaughtyCoder  阅读(154)  评论(0)    收藏  举报