C++进阶语法——智能指针【学习笔记(五)】

news2024/11/20 11:41:39

文章目录

      • 1、智能指针简介
        • 1.1 原始指针(raw pointer)的⼀些问题
        • 1.2 智能指针(smart pointers)
      • 2、智能指针(smart pointers)——unique_ptr
        • 2.1 unique_ptr 的声明
        • 2.2 unique_ptr 的函数
        • 2.3 ⾃定义类型使⽤ unique_ptr
        • 2.4 unique_ptr 不⽀持拷⻉、赋值
        • 2.5 使⽤make_unique初始化(C++14标准)
        • 代码:
      • 3、智能指针(smart pointers)——shared_ptr
        • 3.1 shared_ptr的声明
        • 3.2 shared_ptr的函数
        • 3.3 ⾃定义类型使⽤shared_ptr
        • 3.4 vector和复制操作
        • 3.5 使⽤make_shared初始化(C++11标注)
        • 代码:

1、智能指针简介

1.1 原始指针(raw pointer)的⼀些问题

C++ 提供了内存管理的绝对⾃由度
------->• 分配
------->• 释放
------->• 声明周期管理
⼀些潜在严重问题
------->• 未初始化的指针(wild pointer),也就是野指针,可指向内存的任何位置
------->• 内存泄漏(memory leak),可能因为没有及时释放分配的内存空间
------->• 悬空指针(dangling pointer):指针指向已经释放的对象
所有权(ownership),引入智能指针
------->• 谁拥有指针?
------->• 何时可以删除指针?

1.2 智能指针(smart pointers)

• 也是对象
• 只能指向堆上分配的内存
⽤完后会⾃动删除
• 遵循RAII(资源获取即初始化)原则,对资源的申请释放,是一种成对操作的封装
• 几种C++ 智能指针:
------->• Unique pointers (unique_ptr)
------->• Shared pointers (shared_ptr)
------->• Weak pointers (weak_ptr)
------->• Auto pointers (auto_ptr) (已弃⽤)

  • 导入 #include <memory>
  • 在类模板(class templates)中定义
    • 对原始指针做了封装
    • 重载的操作符
      • 解引⽤(*)
      • 成员选择(->)
      • 不⽀持算数操作符(++, — —等)

创建智能指针的具体实例如下,smart_pointer 可以换成上面提到的 unique_ptr,shared_ptr,weak_ptr,ptr 是指向 Type 类别的智能指针,当运行完 {} 里面的程序时,会自动调用析构函数,会帮助我们处理堆上分配的内存空间,

在这里插入图片描述

2、智能指针(smart pointers)——unique_ptr

  • unique_ptr<T> ptr_name
    • 指向heap堆上类型 T 的对象
    • 唯⼀(unique),多个 unique_ptr 不可以指向同⼀个对象
    • 拥有指向对象的唯⼀所有权
    • 不可以复制或赋值,但可以移动
    • 指针使⽤完毕,被指向的对象会⾃动释放销毁
2.1 unique_ptr 的声明

在这里插入图片描述

2.2 unique_ptr 的函数

在这里插入图片描述

2.3 ⾃定义类型使⽤ unique_ptr

在这里插入图片描述

2.4 unique_ptr 不⽀持拷⻉、赋值

std::move(p1):转移p1拥有的所有权,容器 vec 拥有堆上面对象的所有权,p1 会设置为空指针,

在这里插入图片描述

2.5 使⽤make_unique初始化(C++14标准)

make_unique 的作用也是在堆上创建的内存空间,
auto 关键字是编译器根据 make_unique 的返回值自动帮我们判断数据类型,

在这里插入图片描述

代码:
#include <iostream>
#include <vector>
#include <string>
#include <memory>

using namespace std;

class Account
{
private:
    string name {"account"};
    double balance {0.0};
public:
    Account(string name = "none", double balance = 0.0);
    ~Account();
    bool deposit(double amount);
    void printInfo() const;
    double getBalance();
};

Account::Account(string name, double balance)
    :name {name}, balance {balance}
{
    cout << "构造函数,name: " << name << endl;
}

Account::~Account()
{
    cout << "析构函数,name: " << name << endl;
}
bool Account::deposit(double amount)
{
    balance += amount;
    return true;
}

void Account::printInfo() const
{
    cout << "name: " << name << ", balance: " << balance << endl;
}
double Account::getBalance()
{
    return balance;
}

int main()
{
    
    // Account alice_account {"Alice", 1000.0}; // 构造函数和析构函数都会被调用

    // Account * bob_account = new Account {"Bob", 2000.0}; // 只有构造函数被调用
    // delete bob_account; // 析构函数被调用

    // unique_ptr<Account> p1 {new Account {"jams", 1000.0}}; // 构造函数和析构函数都会被调用

    // auto p2 = make_unique<Account>("mike", 2000.0); // 构造函数和析构函数都会被调用
    // unique_ptr<Account> p3;

    // // p3 = p2; // 报错,因为unique_ptr不允许拷贝,只能移动
    // p3 = move(p2); // p2 会被置为null,即空指针

    // if (! p2)
    //     cout << "p2 is null" << endl;

    // auto p4 = make_unique<Account>("Helen", 3000.0);
    // p4->deposit(1000.0);
    // p4->printInfo(); // 调用成员函数

    vector<unique_ptr<Account>> accounts;
    accounts.push_back( make_unique<Account>("alice",1000));
    accounts.push_back( make_unique<Account>("bob",500));
    accounts.push_back( make_unique<Account>("mike",1000));

    for (const auto &acc: accounts) 
        cout << acc->getBalance() << endl;

    return 0;
}

3、智能指针(smart pointers)——shared_ptr

  • shared_ptr<T> ptr_name
    • 指向heap堆上类型为 T 的对象
    • 不唯⼀,多个shared_ptr可以指向同⼀个对象
    • 被管理对象的所有权在多个shared_ptr中共享
    • 可以复制或赋值
    • 可以移动
    • 引⽤计数(reference count)为0,被指向的对象会⾃动释放销毁
3.1 shared_ptr的声明

当超出 {} 的作用域后,堆上的对象也会自动销毁,

在这里插入图片描述

3.2 shared_ptr的函数

use_count():返回引用计数的值,也就是当前堆上的对象被多少 shared_ptr 管理,
p1.reset() 并没有释放 p1 所指向的对象,因为 p2 还在指向这个对象,

在这里插入图片描述

3.3 ⾃定义类型使⽤shared_ptr

在这里插入图片描述

3.4 vector和复制操作

在这里插入图片描述

3.5 使⽤make_shared初始化(C++11标注)

不再使用关键字 new,编译器也可以生成更高效的执行代码,

在这里插入图片描述

代码:
#include <iostream>
#include <vector>
#include <string>
#include <memory>

using namespace std;

class Account
{
private:
    string name {"account"};
    double balance {0.0};
public:
    Account(string name = "none", double balance = 0.0);
    ~Account();
    void print() const;
};

Account::Account(string name, double balance)
    :name {name}, balance {balance}
{
    cout << "构造函数,name: " << name << endl;
}

Account::~Account()
{
    cout << "析构函数,name: " << name << endl;
}
void Account::print() const
{
    cout << "name: " << name << ", balance: " << balance << endl;
}

void test_func(shared_ptr<Account> p)
{
    cout << "p.use_count(): " << p.use_count() << endl; // 2
}

int main()
{
    // cout << "=====================" << endl;
    // shared_ptr<int> p1 {new int {100}};
    // cout << "p1.use_count(): " << p1.use_count() << endl; // 1

    // shared_ptr<int> p2 {p1}; // 共享所有权
    // cout << "p1.use_count(): " << p1.use_count() << endl; // 2

    // p1.reset(); // 释放所有权,但是不会销毁对象,因为p2还在使用
    // cout << "p1.use_count(): " << p1.use_count() << endl; // 0
    // cout << "p2.use_count(): " << p2.use_count() << endl; // 1


    // cout << "=====================" << endl;
    // shared_ptr<Account> p1 = make_shared<Account>("Alice", 1000.0);
    // test_func(p1);
    // cout << "p1.use_count(): " << p1.use_count() << endl; // 2

    // {
    //     shared_ptr<Account> p2 = p1;
    //     cout << "p2.use_count(): " << p2.use_count() << endl; // 3

    //     {
    //         shared_ptr<Account> p3 = p1;
    //         cout << "p3.use_count(): " << p3.use_count() << endl; // 4
            
    //         p1.reset();
    //     }
    //     cout << "p1.use_count(): " << p1.use_count() << endl; // 2
    //     cout << "p2.use_count(): " << p2.use_count() << endl; // 2
    // }
    // cout << "p1.use_count(): " << p1.use_count() << endl; // 1



    cout << "=====================" << endl;
    shared_ptr<Account> p1 = make_shared<Account>("Alice", 1000.0);
    shared_ptr<Account> p2 = make_shared<Account>("Bob", 2000.0);
    shared_ptr<Account> p3 = make_shared<Account>("Charlie", 3000.0);

    vector<shared_ptr<Account>> accounts;

    accounts.push_back(p1);
    accounts.push_back(p2);
    accounts.push_back(p3);

    for (const auto &p: accounts)
    {
        p->print();
        cout << "p.use_count(): " << p.use_count() << endl; // 1
    }
    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

需要下微信视频号视频的小伙伴们看过来~

随着视频号的热度越来越大&#xff0c;下载视频号视频的需求也开始增加啦&#xff0c;今天给大家给分享几个简单实用的下载方法&#xff0c;总有一个你能用上的&#xff01; 一、犀牛视频下载 犀牛视频下载器可以直接解析并下载视频号短视频。您只需转发视频到机器人即可下载。…

中科驭数受邀亮相两场重要行业盛会,摘得2023“璀璨技术奖”奖项

近日&#xff0c;中科驭数作为DPU算力基础设施领军企业&#xff0c;受邀参与2023信息技术应用创新专题研讨会暨第二届集成电路产业发展创新大会、以及2023AI网络创新大会。在两大行业盛会上&#xff0c;中科驭数与行业知名专家和企业代表齐聚一堂&#xff0c;分享了DPU在集成电…

蓝凌EIS智慧协同平台saveImg接口存在任意文件上传漏洞

蓝凌EIS智慧协同平台saveImg接口存在任意文件上传漏洞 一、蓝凌EIS简介二、漏洞描述三、影响版本四、fofa查询语句五、漏洞复现六、深度复现1、发送如花2、哥斯拉直连 免责声明&#xff1a;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者…

拿下国家级信创认证 中科驭数KPU SWIFT-2200N成为国内首款满足金融业严苛要求的DPU产品

近日&#xff0c;中科驭数KPU SWIFT-2200N低时延DPU卡&#xff0c;在中国人民银行旗下金融信创生态实验室完成测试并取得测试报告&#xff0c;这意味着中科驭数低时延网络代表性产品的应用领域从证券进一步拓展到了银行业&#xff0c;成为国内首款满足金融行业严苛要求的DPU产品…

vue2+antd——实现动态菜单路由功能——基础积累

vue2antd——实现动态菜单路由功能——基础积累 实现的需求&#xff1a;效果图&#xff1a;登录接口处添加以下代码loadRoutes方法内容如下&#xff1a; 最近在写后台管理系统&#xff0c;遇到一个需求就是要将之前的静态路由改为动态路由&#xff0c;使用的后台框架是&#xf…

#智能小车项目(六)麦克纳姆轮x型运动学分析

麦伦介绍 瑞典麦克那姆公司发明的一种全方位移动轮式结构&#xff0c;由基于主体轮辋和一组均匀排布在轮毂周围的回转辊子组成且辊子轴线与轮毂轴线呈一定角度(一般为 45)&#xff0c;小辊子的母线是等速螺旋线或椭圆弧近似而成&#xff0c;当轮子绕着轮毂轴线转动时&#xff…

css画一条虚线,用到background-image:linear-gradient线性渐变的属性

CSS实现虚线的方法_css 虚线_saltlike的博客-CSDN博客 渐变属性(background-image)全解析_background-image linear_大聪明码农徐的博客-CSDN博客 Background:linear-gradient()详解_background: linear-gradient_小白白中之白的博客-CSDN博客 注意&#xff1a; 必须要写高…

QMI8658A_QMC5883L(9轴)-EVB 评估板

1. 描述 QMI8658A_QMC5883L(9轴)-EVB 评估板是一款功能强大的9轴IMU传感器&#xff0c;它利用了QMA8658A 内置的3轴加速度计和3轴陀螺仪&#xff0c;同时结合QMC5883L的3轴地磁数据&#xff0c;来测量物体在三维空间中的角速度和加速度&#xff08;严格意义上的IMU只为用户提供…

在MDP环境下训练强化学习智能体

目录 1.创建MDP环境 2.创建Q-learning智能体 3. 训练Q-learning智能体 4.验证Q-learning结果 本文示例展示了如何训练Q-learning智能体来解决一般的马尔可夫决策过程(MDP)环境。有关这些智能体的更多信息&#xff0c;请参阅Q-Learning智能体。 MDP环境如下图&#xff1a; …

浙江爱知道控股集团,数字化经营的实践者,科技降本增效,助力基业长青

拥抱时代浪潮&#xff0c;加速科技变革。10月27日&#xff0c;浙江爱知道控股集团于西子智慧产业园西子音乐厅举办“AIGC可持续发展峰会”&#xff0c;重点探讨了数字化经营的重要意义。 提高效率和降低成本&#xff1a;数字化经营可以优化和自动化企业的业务流程&#xff0c;提…

Chrome浏览器Snippets调试面板

用Chrome的snippets片段功能创建页面js外挂程序&#xff0c;从控制台创建js小脚本。 Chrome的snippets是小脚本&#xff0c;还可以创作并在Chrome DevTools的来源面板中执行。 可以访问和从任何页面运行它们。当你运行一个片段&#xff0c;它从当前打开的页面的上下文中执行。 …

达索系统SOLIDWORKS 2024 装配体新增功能

如今市场环境紧迫&#xff0c;许多企业在这样的情形之下&#xff0c;都需要尽快将产品推向市场&#xff0c;赢得头筹。所以产品设计需要快速进行装配验证&#xff0c;以确保产品功能和性能的准确性和可靠性&#xff0c;同时原型或样机的制造和装配需要尽快完成&#xff0c;以满…

HEC-RAS模型教程

详情点击公众号链接&#xff1a;HEC-RAS模型教程 前言 水动力与水环境模型的数值模拟是实现水资源规划、环境影响分析、防洪规划以及未来气候变化下预测和分析的主要手段。 一&#xff0c;水动力模型 1.水动力模型的本质 2.水动力模型的基本方程与适用范围 3.模型建模要点…

地球系统模式CESM

目前通用地球系统模式&#xff08;Community Earth System Model&#xff0c;CESM&#xff09;在研究地球的过去、现在和未来的气候状况中具有越来越普遍的应用。CESM由美国NCAR于2010年07月推出以来&#xff0c;一直受到气候学界的密切关注。近年升级的CESM2.0在大气、陆地、海…

接口测试,一篇搞定

大多数人对于接口测试都觉得是一种高大上的测试&#xff0c;觉得学会接口测试就可以从小白测试员&#xff0c;变成了高级测试员&#xff0c;但其实接口测试只是测试的基础内容 什么是接口 接口泛指实体把自己提供给外界的一种抽象化物&#xff08;可以为另一实体&#xff09;&…

Java List Set Map

一、List 1.1 ArrayList 1.2 LinkedList 二、Set 2.1 HashSet 2.2 TreeSet 2.3 LinkedHashSet 三、Map 3.1 HashMap 3.2 TreeMap 3.3 LinkedHashMap 四、对比 类型底层结构重复null值场景备注查询删除新增ListArrayList动态数组可允许快速随机访问元素0(1)0(n)尾部增加0&a…

MFC 重绘static控件,使用png、jpg图片贴图

MFC实现static静态文件贴图png,底部有完整工程链接免费下载 一、添加变量 二、使用CPngStatic类型添加对应的m_sta1类变量 三、在init初始化代码内增加加载图片代码 四、最终效果 参考按钮实现添加GDI 按钮贴图实现 VS2015完整工程下载 下载链接

一文读懂防火墙基本原理

你们好&#xff0c;我的网工朋友。 今天想和你聊聊防火墙。防火墙是啥&#xff1f;表意自然是防止火灾发生时&#xff0c;火势烧到其它区域&#xff0c;使用由防火材料砌的墙。 后来这个词语引入到了网络中&#xff0c;把从外向内的网络入侵行为看做是火灾&#xff0c;防止这种…

SHCTF 2023 新生赛 Web 题解

Web [WEEK1]babyRCE 源码过滤了cat 空格 我们使用${IFS}替换空格 和转义获得flag [WEEK1]飞机大战 源码js发现unicode编码 \u005a\u006d\u0078\u0068\u005a\u0033\u0074\u006a\u0059\u006a\u0045\u007a\u004d\u007a\u0067\u0030\u005a\u0069\u0030\u0031\u0059\u006d\u0045…