智能指针weak_ptr为弱共享指针,实际上是share_ptr的辅助指针,不具备指针的功能。主要是为了协助 shared_ptr 工作,可用来观测资源的使用情况。weak_ptr 只对 shared_ptr 进行引用,而不改变其引用计数,当被观察的 shared_ptr 失效后,相应的 weak_ptr 也相应失效。use_count() 可以观测资源的引用计数,lock()返回一个对象的可用的share_ptr,若weak_ptr.expired()为true过期,则返回一个空的share_ptr。

构造:

std::shared_ptr<int> sp(new int);
std::weak_ptr<int> wp1;
std::weak_ptr<int> wp2(wp1);
std::weak_ptr<int> wp3(sp);
std::cout << "use_count:\n";
std::cout << "wp1: " << wp1.use_count() << '\n';
std::cout << "wp2: " << wp2.use_count() << '\n';
std::cout << "wp3: " << wp3.use_count() << '\n';

输出引用计数:

过期判断:

std::shared_ptr<int> shared(new int());
std::weak_ptr<int> weak(shared);
std::cout << "1. weak " << (weak.expired() ? "is" : "is not") << " expired\n";
shared.reset();
std::cout << "2. weak " << (weak.expired() ? "is" : "is not") << " expired\n";

输出:

lock()返回可用的share_ptr或空share_ptr

std::shared_ptr<int> sp1, sp2;
std::weak_ptr<int> wp;
sp1 = std::make_shared<int>(); // sp1
wp = sp1; // sp1, wp
sp2 = wp.lock(); // sp1, wp, sp2
sp1.reset(); // wp, sp2
sp1 = wp.lock(); // sp1, wp, sp2
std::cout << "*sp1: " << *sp1 << '\n';
std::cout << "*sp2: " << *sp2 << '\n';

输出:

#########################################################################################################

一个问题:shared_ptr是采用引用计数的智能指针,多个shared_ptr可以指向同一个动态对象,并共用了一个引用计数器。因此会出现循环引用的问题,导致计数器无法减一,因而内容在该销毁的地方没有释放。

eg:

class Brother;
class Sister
{
public:
Sister() { cout << "Sister Constructor..." << endl; }
~Sister() { cout << "Sister Destructor..." << endl; }
shared_ptr<Brother> _bro;
};
class Brother
{
public:
Brother() { cout << "Brother Constructor..." << endl; }
~Brother() { cout << "Brother Destructor..." << endl; }
shared_ptr<Sister> _sis;
}; shared_ptr<Sister> sps = make_shared<Sister>();
shared_ptr<Brother> spb = make_shared<Brother>();
sps->_bro = spb;
spb->_sis = sps;
std::cout << "sps use_cout:" << sps.use_count() << std::endl;
std::cout << "spb use_cout:" << spb.use_count() << std::endl;

输出:

引用计数器为2,析构函数没有调用,出现程序执行完内容没有释放。

使用weak_ptr来处理这一问题,只需要将相互引用使用weak_ptr来替换share_ptr的引用即可

class Sister
{
public:
Sister() { cout << "Sister Constructor..." << endl; }
~Sister() { cout << "Sister Destructor..." << endl; }
weak_ptr<Brother> _bro;
};
class Brother
{
public:
Brother() { cout << "Brother Constructor..." << endl; }
~Brother() { cout << "Brother Destructor..." << endl; }
weak_ptr<Sister> _sis;
};

同样的输出代码:

正常析构,程序执行完释放内容。

智能指针weak_ptr记录的更多相关文章

  1. c/c++ 智能指针 weak_ptr 使用

    智能指针 weak_ptr 使用 weak_ptr用途: 1,解决空悬指针问题 2,解决循环引用问题 weak_ptr特点:没有*操作和->操作 weak_ptr是不控制所指对象生存周期的智能指 ...

  2. C++智能指针--weak_ptr

    weak_ptr是对对象的一种弱引用,它不会添加对象的引用计数.weak_ptr和shared_ptr之间能够相互转换.shared_ptr能够直接赋值给week_ptr,week_ptr可通过调用l ...

  3. Boost智能指针——weak_ptr

    循环引用: 引用计数是一种便利的内存管理机制,但它有一个很大的缺点,那就是不能管理循环引用的对象.一个简单的例子如下: #include <string>#include <iost ...

  4. 智能指针share_ptr记录

    shared_ptr 是一个共享所有权的智能指针,允许多个指针指向同一个对象.shared_ptr 对象除了包括一个对象的指针,还包括一个引用计数器.当每给对象分配一个share_ptr的时候,引用计 ...

  5. 智能指针weak_ptr解决循环依赖问题

    #include <iostream> #include <memory> class Woman; class Man{ private: std::weak_ptr< ...

  6. 智能指针unique_ptr记录

    unique_ptr 对对象独有管理,无法复制,共享,值传递,可以使用move语义来转移控制权. std::default_delete<int> d; std::unique_ptr&l ...

  7. [6] 智能指针boost::weak_ptr

    [1]boost::weak_ptr简介 boost::weak_ptr属于boost库,定义在namespace boost中,包含头文件 #include<boost/weak_ptr.hp ...

  8. weak_ptr<T>智能指针

    weak_ptr是为配合shared_ptr而引入的一种智能指针,它更像是shared_ptr的一个助手,而不是智能指针,因为它不具有普通指针的行为,没有重载operator*和operator-&g ...

  9. 智能指针shared_ptr新特性shared_from_this及weak_ptr

    enable_shared_from_this是一个模板类,定义于头文件<memory>,其原型为: template< class T > class enable_shar ...

随机推荐

  1. python flask 如何读取数据库数据并返回到html

    app.py from flask import Flask from flask import render_template from flask_bootstrap import Bootstr ...

  2. Django-报错信息及admin后台汉化

    django-admin 汉化 效果对比 django admin 后台 报错信息 配置 修改配置文件中的 LANGUAGE_CODE 与 TIME_ZONE 即可. 将 django admin 后 ...

  3. Creating mailbox file: 文件已存在

    原来linux下添加用户后,会在系统里自动加一个邮箱(系统邮箱),路径是:/var/spool/mail/用户名.可以直接用命令#rm -rf /var/spool/mail/用户名 这样就可以再次添 ...

  4. docker-get拉取镜像

    docker-get Let you get all docker images without having network problem. Install curl -kLO https://s ...

  5. kafka常见问题

    (1)  如果想消费已经被消费过的数据 consumer是底层采用的是一个阻塞队列,只要一有producer生产数据,那consumer就会将数据消费.当然这里会产生一个很严重的问题,如果你重启一消费 ...

  6. Django rest-framework框架-认证组件的简单实例

    第一版 : 自己写函数实现用户认证 #models from django.db import models #用户表 class UserInfo(models.Model): user_type_ ...

  7. springcloud必知功能使用教程

    springcloud Spring Cloud是一系列框架的有序集合.它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册.配置中心.消息总线.负载均衡.断路 ...

  8. split分离特殊字符

    Invalid escape sequence (valid ones are  \b  \t  \n  \f  \r  \"  \'  \\ ) \b  \t  \n  \f  \r  \ ...

  9. linux下Django Nginx+uwsgi 安装配置

    原文链接 在前面的章节中我们使用 python manage.py runserver 来运行服务器.这只适用测试环境中使用. 正式发布的服务,我们需要一个可以稳定而持续的服务器,比如apache, ...

  10. 报错处理(UnicodeEncodeError: 'gbk' codec can't encode character '\xa0' in position 2: ill egal multibyte sequence)

    参照文[https://blog.csdn.net/Dillon2015/article/details/53204955]的说法, 第一个错 [UnicodeEncodeError:'gbk' co ...