C++之boost智能指针

1、boost智能指针

资源获取即初始化:在构造函数中对资源进行初始化,在析构函数中释放。

智能指针的本质思想是:将堆对象的生存期,用栈对象来管理。这个栈对象就是智能指针。

当new 一个堆对象的时候,立刻用智能指针来接管,

具体做法是:在构造函数进行初始化(用一个指针指向堆对象),在析构函数中调用delete来释放堆对象。

由于智能指针本身是一个栈对象,它的作用域结束的时候,自动调用析构函数,从而调用了delete释放了堆对象。

2、scoped_ptr<T>

#include <iostream>
#include <boost/smart_ptr.hpp>
using namespace std;

class X
{
public:
    X()
    {
        cout << "X ..." << endl;
    }
    ~X()
    {
        cout << "~X ..." << endl;
    }
};

int main() {
    cout << "entering main ..." << endl;
    {
        // 将p放在这个{}中,出了这个{},作用域就消失了
        boost::scoped_ptr<X> p(new X);
        // 既不能被拷贝,也不能被赋值(下面这样编译报错,因为在scoped_ptr里里面,拷贝构造和=运算符都是声明成私有的)
        // boost::scoped_ptr<X> p(p);
    }

    std::cout << "Hello, World!" << std::endl;
    return 0;
}

// 输出
entering main ...
X ...
~X ...
Hello, World!

3、share_ptr<T>

如果我们都不调用reset的话,当p1和p2这两个栈上的变量也会自动销毁,销毁的时候也会自动去调用reset。

为什么说shared_ptr是线程安全的?因为在做加法的时候,是一个原子操作BOOST_INTERLOCKED_INCREMENT。

#include <iostream>
#include <boost/smart_ptr.hpp>
#include <boost/shared_ptr.hpp>
using namespace std;

class X
{
public:
    X()
    {
        cout << "X ..." << endl;
    }
    ~X()
    {
        cout << "~X ..." << endl;
    }
};

int main() {
    cout << "entering main ..." << endl;

    boost::shared_ptr<X> p1(new X);
    cout << p1.use_count() << endl;

    boost::shared_ptr<X> p2(p1);
    cout << p2.use_count() << endl;

    boost::shared_ptr<X> p3;
    p3 = p1;
    cout << p2.use_count() << endl;

    p1.reset();
    cout << p2.use_count() << endl;

    p2.reset();
    cout << p2.use_count() << endl;

    std::cout << "exiting main ..." << std::endl;
    return 0;
}

// 输出
entering main ...
X ...
1
2
3
2
0
exiting main ...
~X ...

share_ptr<T>注意事项

循环引用(这样的情况下,销毁的时候内部放入引用还都是1,所以不会调用析构函数)

解决方案:手动将引用减一

#include <iostream>
#include <boost/smart_ptr.hpp>
#include <boost/shared_ptr.hpp>
using namespace std;

class Child;
class Parent;
typedef boost::shared_ptr<Parent> parent_ptr;
typedef boost::shared_ptr<Child> child_ptr;

class Child
{
public:
    Child()
    {
        cout << "Child ..." << endl;
    }
    ~Child()
    {
        cout << "~Child ..." << endl;
    }
    parent_ptr parent_;
};

class Parent
{
public:
    Parent()
    {
        cout << "Parent ..." << endl;
    }
    ~Parent()
    {
        cout << "~Parent ..." << endl;
    }
    child_ptr child_;
};

int main() {
    parent_ptr parent(new Parent);
    child_ptr child(new Child);
    parent->child_ = child;
    child->parent_ = parent;

    parent->child_.reset();
    return 0;
}

// 输出
Parent ...
Child ...
~Child ...
~Parent ...

还有一种解决方式,是通过weak_ptr来解决。

4、weak_ptr<T>

#include <iostream>
#include <boost/smart_ptr.hpp>
#include <boost/shared_ptr.hpp>
using namespace std;

class Child;
class Parent;
typedef boost::shared_ptr<Parent> parent_ptr;
typedef boost::shared_ptr<Child> child_ptr;

class Child
{
public:
    Child()
    {
        cout << "Child ..." << endl;
    }
    ~Child()
    {
        cout << "~Child ..." << endl;
    }
    parent_ptr parent_;
};

class Parent
{
public:
    Parent()
    {
        cout << "Parent ..." << endl;
    }
    ~Parent()
    {
        cout << "~Parent ..." << endl;
    }
    //child_ptr child_;
    boost::weak_ptr<Child> child_;
};

int main() {
    parent_ptr parent(new Parent);  // 1
    child_ptr child(new Child);     // 1
    parent->child_ = child;            // 1
    child->parent_ = parent;           // 2

//    parent->child_.reset();
    return 0;
}

// 输出
Parent ...
Child ...
~Child ...
~Parent ...

通过weak_ptr访问成员的时候,要提升到share_ptr

#include <iostream>
#include <boost/smart_ptr.hpp>
#include <boost/shared_ptr.hpp>
using namespace std;

class X
{
public:
    X()
    {
        cout << "X ..." << endl;
    }
    ~X()
    {
        cout << "~X ..." << endl;
    }
    void Fun()
    {
        cout << "Fun ..." << endl;
    }
};

int main() {
    boost::weak_ptr<X> p;
    {
        boost::shared_ptr<X> p2(new X);
        cout << p2.use_count() << endl;
        p = p2;
        cout << p2.use_count() << endl;

        boost::shared_ptr<X> p3 = p.lock();  // lock()表示提升为shared_ptr
        if (!p3)
        {
            cout << "object is destroyed " << endl;
        }
        else
        {
            p3->Fun();
        }
    }

    boost::shared_ptr<X> p4 = p.lock();
    if(!p4)
    {
        cout << "object is destroyed " << endl;
    }
    else
    {
        p4->Fun();
    }

    return 0;
}
// 输出
X ...
1
1
Fun ...
~X ...
object is destroyed

5、PIMPL

问题原因:嵌套了多重头文件,编译速度降低;因为类Y中有X的对象,这样如果X类改变,所有Y的对象都需要重新编译,因为此时类Y的大小已经改变,这样客户程序就不仅仅依赖于接口,还依赖于库里面的具体实现。

解决方法:将包含头文件改成声明类;将对象改成指针(32位的4个字节,64位8个字节,这是不会变化的)

如果一定要使用到类的对象的话,那就把类的对象都抽象到同一个类Impl中,然后通过Impl的指针来访问

class Y
{
    Impl P;
};

class Impl
{
    A a;
    B b;
    C c;
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/770872.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

共享拼购:创新商业模式引领小用户基数下的销售奇迹“

在瞬息万变的商业蓝海中&#xff0c;一个新颖且深具潜力的策略正悄然改变着游戏规则&#xff0c;它巧妙地避开了传统路径的束缚&#xff0c;以微妙却深远的调整&#xff0c;开辟出了一条通往成功的独特航道。我的一位合作伙伴&#xff0c;正是这一策略的实践者&#xff0c;他在…

Blender渲染慢?那是你还不知道这5个技巧

Blender是一款功能强大且用途广泛的软件&#xff0c;可帮助 3D 艺术家和动画师创作出色的视觉内容。如果您使用过 Blender&#xff0c;您就会知道渲染可能非常耗时。渲染时间过长可能会令人烦恼并限制创造力。 在这篇文章中&#xff0c;我们将提供一些专家提示和想法以加快 Bl…

交换机需要多大 buffer

有点违背直觉&#xff0c;但是真事儿&#xff0c;交换机过境的流越多&#xff0c;所需 buffer 越小&#xff0c;这是为什么&#xff1f; 范氏(范雅各布森&#xff0c;van jacobson)管道的 aimd 流建议 buffer_size 为 bdp&#xff0c;这很容易理解&#xff0c;因为 aimd 流最小…

OpenCV库Windows端编译方法

编译前提 &#xff08;1&#xff09;下载好所需版本的OpenCV源码&#xff0c;点击进入下载地址&#xff0c;此处以OpenCV-2.4.13.6为例&#xff0c;下载页面截图如下图所示&#xff1a; 解压后如下图所示&#xff1a; &#xff08;2&#xff09;安装好CMake软件&#xff0c;点…

规则·理解·成长:与自闭症儿童共绘记忆蓝图

在星贝育园&#xff0c;作为专注于自闭症儿童康复的专业教育者&#xff0c;我们常常遇到家长的疑惑&#xff1a;“为什么我的孩子总是记不清楚规则&#xff1f;”这个问题触及了自闭症谱系障碍&#xff08;ASD&#xff09;儿童在理解与遵守规则方面面临的独特挑战。下面&#x…

软考中级系统集成项目管理工程师备考笔记

目录 一&#xff0c;通用内容 &#xff08;一&#xff09;信息与信息化 1.1&#xff0c;信息 信息基本概念 信息的传输模型 信息的质量属性 1.2&#xff0c;信息系统 信息系统的基本概念 信息系统定义 信息系统集成 1.3&#xff0c;信息化 信息化层次 信息化的核心…

【Redis】SpringBoot连接Redis

1. 创建项目并配置文件 勾选NoSQL中的 Spring Data Redis。当然,把 Web 中的 SpringWeb 也勾选一下.方便写接口进行后续测试。 在 application.yml 中配置 2. 不同数据类型使用Demo 在SpringBoot中&#xff0c;为我们提供了StringRedisTemplate类&#xff0c;供我们处理一些文…

MYSQL8.0环境部署

创建用户 groupadd mysql useradd -g mysql mysql 删除原来的包 # rpm -qa|grep mysql # rpm -qa|grep mari mariadb-libs-5.5.68-1.el7.x86_64 # rpm -e --nodeps mariadb-libs-5.5.68-1.el7.x86_64 解压 cd /usr/local & mkdir mysql cd mysql # cp mysql-8…

tauri使用github action实现跨平台编译并解决编译错误,mac已损坏,无法打开,你应该将它移到废纸篓解决办法

正常编译为跨平台结果就像上面的&#xff0c;有mac/windows/linux的安装程序&#xff0c;直接下载就可以安装使用&#xff0c;我的这个livebox桌面端仓库地址&#xff1a;GitHub - Sjj1024/LiveBox: livebox&#xff0c;里面有编译文件可以参考。今天主要讲一下遇到的问题。 官…

视频文字提取在线怎么做?5个高效提取字幕的实用方法

无论是社交媒体上的短视频&#xff0c;还是在线教育的课程视频&#xff0c;字幕都成为了不可或缺的一部分。它们不仅帮助听力障碍人士更好地理解内容&#xff0c;还能让非母语观众更容易跟上节奏。 一提到字幕&#xff0c;我们可能会想到用它来做笔记&#xff0c;但要从视频中…

UVa1321/LA2925 Dice contest

UVa1321/LA2925 Dice contest 题目链接题意分析测试数据AC 代码 题目链接 本题是2003年icpc欧洲区域赛中欧赛区的D题 题意 骰子的六面展开图如下&#xff0c;现在把骰子的六个面赋予一套权重 w i ( 1 ≤ w i ≤ 50 , 1 ≤ i ≤ 6 ) w_i(1\le w_i \le 50,1\le i\le 6) wi​(1≤…

米国政府呼吁抛弃 C 和 C++

在开始前刚好我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「C的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff01; 很多观点认为C 或 C永远不可被…

同步互斥与通信

目录 一、同步与互斥的概念 二、同步与互斥并不简单 三、各类方法的对比 一、同步与互斥的概念 一句话理解同步与互斥&#xff1a;我等你用完厕所&#xff0c;我再用厕所。 什么叫同步&#xff1f;就是&#xff1a;哎哎哎&#xff0c;我正在用厕所&#xff0c;你等会。 什…

nginx.conf配置参数解析

nginx配置文件解析 /usr/local/nginx/conf vim /etc/security/limits.conf #配置生效只能重新启动* soft nproc 65535 #能打开的进程最大数是软限制655335,65535是最大值 * hard nproc 65535 * soft nofile 65535 # 进程打开文件数的最大值65535 * hard nof…

最新美联储会议纪要:通胀降温,但不急于降息!

KlipC报道&#xff1a;当地时间周三&#xff0c;美联储公布了6月货币政策会议纪要。纪要显示&#xff0c;数据表明有通胀放缓的迹象&#xff0c;但如果降息需要更多的证据。此外&#xff0c;多位与会者表示&#xff0c;货币政策应随时准备应对意外的经济疲软。 会议纪要显示&a…

python-字典

为什么需要字典 字典的定义 字典数据的获取 字典的嵌套 嵌套字典的内容获取 字典的注意事项&#xff1a; 字典的常用操作 新增元素 更新元素 删除元素 清空字典 汇总 字典的特点

收银系统源码-收银台营销功能-定时折扣

1. 功能描述 定时折扣&#xff1a;在特定的时间段&#xff0c;将商品以打折的方式在收银台售卖&#xff0c;例如生鲜行业&#xff0c;由于生鲜是易耗品&#xff0c;很多门店晚上都会通过打折的方式进行促销&#xff1b; 2.适用场景 新门店开业、门店周年庆、节假日等特定时间…

深度分析和对比本地大语言模型Ollama和LocalAI

前言 在充满活力的人工智能&#xff08;AI&#xff09;世界中&#xff0c;开源工具已成为开发人员和组织利用LLM&#xff08;大型语言模型&#xff09;力量的重要资源。这些工具通过提供对高级LLM模型的访问权限&#xff0c;使各种用户能够构建创新和前沿的解决方案。在众多可…

springboot @configuration注解的配置, @bean注解方法a, 在@bean注解 getb(){}需要注入a

深度解析Configuration注解 /*** General purpose AOP callback. Used when the target is dynamic or when the* proxy is not frozen.*/private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {private final AdvisedSupport advised;…

实验九 存储过程和触发器

题目 创建并执行一个无参数的存储过程proc_product1&#xff0c;通过该存储过程可以查询商品类别名称为“笔记本电脑”的商品的详细信息&#xff1a;包括商品编号、商品名称、品牌、库存量、单价和上架时间信息 2、创建并执行一个带输入参数的存储过程proc_product2&#xff…