Th5.4:智能指针(weak_ptr)之详述

本小节回顾学习的知识点分别是weak_ptr常用的概述常用操作尺寸等问题

今天总结的知识分为以下3个大点:

(1)weak_ptr概述
    (1.1)weak_ptr的创建
(2)weak_ptr的常用操作
    (2.1)use_count()
    (2.2)expired()
    (2.3)reset()
    (2.4)lock()
(3)尺寸问题

(1)weak_ptr概述:

        weak_ptr:“弱共享”/“弱引用”,作用:监视shared_ptr(强引用)的生命周期/用以辅助shared_ptr进行工作的!(人话:weak_ptr可以监视到它所指向的对象是否还存在!)

weak“弱”,反义词“强”。弱指的是weak_ptr,而强指的是shared_ptr。这里的弱就弱在weak_ptr控制不了所指向对象的生存期。且weak_ptr不是一种独立的智能指针,它依赖于shared_ptr而存在!。

        解释:weak_ptr也是一个类模板,也是一个智能指针。这个weak_ptr智能指针是指向一个由shared_ptr管理的对象的!但是,这个weak_ptr智能指针是不控制所指向对象的生命周期的!
换句话说:将weak_ptr绑定到shared_ptr所指向的对象时并不会改变shared_ptr的引用计数!

        注意①weak_ptr的构造和析构是不会增加或减少shared_ptr所指向对象的引用计数的!但是“弱”引用计数会改变,也即改变weak_ptr的引用计数!!!

        注意②当shared_ptr所指向的对象的引用计数从1-》0时,需要释放其所指向的对象,那么不论是否有别的weak_ptr指向该对象,都会正常让shared_ptr释放其所指向的对象

        注意③:只有强(也既shared_ptr的)引用计数才会影响对象的生命周期,弱(也既weak_ptr的)引用计数是不会影响对象的生命周期的!

(1.1)weak_ptr的创建:

请看以下的代码:

shared_ptr sp = make_shared(1);//创建一个shared_ptr指针
weak_ptr wp(sp);//用shared_ptr来初始化weak_ptr

(2)weak_ptr的常用操作
    (2.1).use_count():    

        .use_count()方法的功能是:用以获取与其共享的所指向对象的其他shared_ptr指针的数量,或者说获取当前“强引用”所管理的资源的引用计数的个数。

请看以下的代码:

auto pi = make_shared(111);
auto pi2(pi);//pi2是一个shared_ptr
weak_ptr piw(pi);
int n = piw.use_count();
cout << "n = " << n << endl;

运行结果:

    (2.2).expired():    

        .expired()方法的功能是:用来判断所观测到资源是否已经被释放了(即判断.use_count()方法是否为0,为0就表示该强引用所指向对象就不存在了,过期了;否则就表示还没过期,也即强引用所指向的对象还存在~)过期,返回true;未过期,返回false;

请看以下的代码:

auto pi = make_shared(111);
auto pi2(pi);//pi2是一个shared_ptr
weak_ptr piw(pi);
int n = piw.use_count();
cout << "n = " << n << endl;
pi.reset();
pi2.reset();
if (piw.expired()) {
	cout << "该weak_ptr所指向的资源已经被释放了!" << endl;
}

 运行结果:

   (2.3).reset():

        .reset()方法的功能是:在弱引用weak_ptr中,.reset()方法的作用是将该弱引用指针设置为空nullptr,但不影响指向该对象的强引用数量,只会使得其弱引用数量减少。

请看以下的代码:

auto pi = make_shared(111);
auto pi2(pi);//pi2是一个shared_ptr
weak_ptr piw(pi);
weak_ptr piw2(pi);
piw.reset();
piw2.reset();

运行结果:

        在执行piw.reset()这行代码前的运行结果:

        在执行了piw.reset()这行代码后的运行结果:

        在执行了piw2.reset()这行代码后的运行结果:

 

可见,weak_ptr智能指针的.reset()方法会使得弱引用次数减少,但是不会影响强引用次数。

   (2.4).lock():

        .lock()方法的功能是:判断weak_ptr所指向的shared_ptr对象是否存在。若存在,则这个lock方法会返回一个指向该对象的shared_ptr指针;若它所指向的这个shared_ptr对象不存在,则lock()函数会返回一个空的shared_ptr。

请看以下代码:

auto p1 = make_shared(42);
weak_ptr pw;
pw = p1;//用shared_ptr给weak_ptr赋值
if (!pw.expired()) {
	auto p2 = pw.lock();//.lock()方法返回一个shared_ptr,并且此时强引用计数为2
	if (p2) {
		//p2非空,表明pw所指向的shared_ptr所管理的对象此时没有expire
		cout << "p2还在呢!" << endl;
	}
	else {
		cout << "p2不在了呢!" << endl;
	}
}

(3)尺寸(占用的内存空间)问题:

        weak_ptr的尺寸和shared_ptr的尺寸是一样大的,都是裸指针的2倍。且他们都有2种指针,一个都指向T类型的对象,另一个都指向同一个控制块

Th5.4:智能指针(weak_ptr)之详述_第1张图片

        它们的第一个指针都指向某类型的对象,第二个指针都指向一个很大的数据类型:控制块。这个控制块含有:

        1---所指向对象的强引用计数

        2---所指向对象的弱引用计数

        3---其他data:比如自定义的删除器指针等等

请看以下代码:

weak_ptr pw;
int a = 1;
int* p = &a;
cout << sizeof(p) << endl;//8字节 
cout << sizeof(pw) << endl;//16字节 = 2 * 8 字节

        以上就是我总结的关于weak_ptr常用的概述常用操作尺寸等问题的笔记。希望你能读懂并且消化完,也希望自己能牢记这些小小的细节知识点,加油吧,我们都在coding的路上~

你可能感兴趣的:(C++,学习笔记or记录+总结,p2p,linq,gnu)