当前位置: 首页 > article >正文

C++ 学习第22天:智能指针与异常处理

往期回顾:

C++ 入门19:STL 容器之优先队列(priority_queue)-CSDN博客

C++ 入门第 20 天:STL 容器之无序集合与无序多重集合-CSDN博客

C++ 入门第 21 天:STL 容器之无序映射与无序多重映射-CSDN博客


C++ 学习第22天:智能指针与异常处理

前言

今天我们将学习 C++ 的两个重要概念:智能指针异常处理

  • 智能指针:C++11 引入的智能指针可以帮助我们更安全地管理动态分配的内存,避免内存泄漏。
  • 异常处理:C++ 提供了异常处理机制,让我们可以捕获并处理程序运行中的错误。

1. 智能指针(Smart Pointers)

1.1 智能指针概述

智能指针是 C++11 引入的一个重要特性,用于自动管理动态分配的内存资源。它们使得开发者不再需要手动 delete 内存,减少了内存泄漏的风险。C++ 标准库提供了三种智能指针:

  • unique_ptr:独占式智能指针,每个 unique_ptr 独占一个资源,不能复制,但可以转移所有权。
  • shared_ptr:共享式智能指针,允许多个指针共享同一个资源,通过引用计数管理内存。
  • weak_ptr:弱引用智能指针,它不会影响引用计数,主要用于解决 shared_ptr 的循环引用问题。

1.2 unique_ptr 示例

unique_ptr 是最简单的智能指针,它提供了对资源的独占控制。unique_ptr 不能被复制,只能通过 std::move() 转移所有权。

#include <iostream>
#include <memory>
using namespace std;

int main() {
    // 创建一个 unique_ptr,指向动态分配的整数
    unique_ptr<int> p1 = make_unique<int>(10);
    cout << "Value pointed by p1: " << *p1 << endl;

    // 使用 std::move 转移所有权
    unique_ptr<int> p2 = move(p1);  // p1 现在为空,所有权已转移到 p2
    if (!p1) {
        cout << "p1 is now empty." << endl;
    }
    cout << "Value pointed by p2: " << *p2 << endl;

    return 0;
}

输出结果

Value pointed by p1: 10
p1 is now empty.
Value pointed by p2: 10

1.3 shared_ptr 示例

shared_ptr 允许多个智能指针共享同一块资源,并通过引用计数来管理资源的生命周期。当所有 shared_ptr 对象都超出作用域时,资源会被自动释放。

#include <iostream>
#include <memory>
using namespace std;

int main() {
    // 创建一个 shared_ptr,指向动态分配的整数
    shared_ptr<int> p1 = make_shared<int>(20);
    shared_ptr<int> p2 = p1;  // p1 和 p2 共享同一个资源

    cout << "Value pointed by p1: " << *p1 << endl;
    cout << "Value pointed by p2: " << *p2 << endl;

    cout << "Use count of shared_ptr: " << p1.use_count() << endl;  // 输出引用计数

    return 0;
}

 输出结果

Value pointed by p1: 20
Value pointed by p2: 20
Use count of shared_ptr: 2

1.4 weak_ptr 示例

weak_ptr 是一种不增加引用计数的智能指针。它常用来解决 shared_ptr 引起的循环引用问题。

#include <iostream>
#include <memory>
using namespace std;

int main() {
    shared_ptr<int> p1 = make_shared<int>(30);
    weak_ptr<int> w1 = p1;  // 创建一个 weak_ptr,不影响引用计数

    if (auto p2 = w1.lock()) {  // lock() 获取一个 shared_ptr
        cout << "Weak pointer is valid, value: " << *p2 << endl;
    } else {
        cout << "Weak pointer is expired." << endl;
    }

    return 0;
}

 输出结果

Weak pointer is valid, value: 30

1.5 智能指针应用场景

  • 自动内存管理:使用智能指针可以有效管理内存,避免内存泄漏和悬挂指针。
  • 避免循环引用weak_ptr 可以有效地打破 shared_ptr 之间的循环引用,防止内存无法释放。

2. C++ 异常处理(Exception Handling)

2.1 异常处理概述

C++ 提供了 trycatchthrow 关键字,用于捕获和处理运行时的错误(异常)。通过异常处理,我们能够在程序出错时不中断程序的运行,而是进行适当的处理。

  • try:尝试执行可能引发异常的代码。
  • throw:当发生异常时,抛出异常对象。
  • catch:捕获并处理抛出的异常。

2.2 异常处理基本结构

#include <iostream>
using namespace std;

int divide(int a, int b) {
    if (b == 0) {
        throw "Division by zero error";  // 抛出异常
    }
    return a / b;
}

int main() {
    try {
        cout << divide(10, 0) << endl;  // 会抛出异常
    } catch (const char* msg) {
        cout << "Caught exception: " << msg << endl;  // 捕获并处理异常
    }

    return 0;
}

输出结果:        

Caught exception: Division by zero error

2.3 异常处理中的常见问题

  • 异常安全性:为了保证在异常发生时资源能够正确释放,尽量使用 RAII(资源获取即初始化)模式。
  • 自定义异常类型:我们可以通过定义自定义的异常类,来实现更加细粒度的异常处理。

2.4 自定义异常类示例

#include <iostream>
#include <stdexcept>  // 提供标准异常类
using namespace std;

class DivisionByZeroException : public exception {
public:
    const char* what() const noexcept override {
        return "Division by zero error";  // 重载 what() 方法,返回自定义异常信息
    }
};

int divide(int a, int b) {
    if (b == 0) {
        throw DivisionByZeroException();  // 抛出自定义异常
    }
    return a / b;
}

int main() {
    try {
        cout << divide(10, 0) << endl;  // 会抛出异常
    } catch (const DivisionByZeroException& ex) {
        cout << "Caught exception: " << ex.what() << endl;  // 捕获并处理自定义异常
    }

    return 0;
}

输出结果

Caught exception: Division by zero error

2.5 异常处理应用场景

  • 输入验证:捕获并处理非法输入。
  • 文件操作:捕获文件读写过程中可能出现的异常。
  • 内存分配:捕获内存分配失败等异常情况。

结语

以上就是 C++ 中两个重要的特性 智能指针异常处理 的基础知识点了。智能指针unique_ptrshared_ptrweak_ptr 能有效管理内存,避免内存泄漏,并解决循环引用问题。异常处理:C++ 提供了 trythrowcatch 来处理程序中的异常,可以保证程序在发生错误时不会崩溃,而是通过捕获和处理异常来继续执行。这两个概念对于编写更健壮、可靠的 C++ 程序非常重要,大家多看看,一定要掌握。

都看到这里了,点个赞再走呗朋友~

加油吧,预祝大家变得更强!


http://www.kler.cn/a/458120.html

相关文章:

  • 硬件工程师面试题 21-30
  • 2024西北工业大学noj(C语言)记录全100题
  • 【pytorch】conda安装pytorch
  • 路由器静态路由配置
  • Flink源码解析之:如何根据算法生成StreamGraph过程
  • 【每日学点鸿蒙知识】长按动画、Canvas与底部导航重叠、Grid拖动、Web宽度自适应
  • # 【超全面了解鸿蒙生命周期】-生命周期补充
  • 快速打造智能应用:从设计到上线的全流程指南
  • LeetCode 82:删除排序链表中的重复元素 II
  • 【MySql】2020-03-12 Windows安装MySQL5.7.28
  • Microi吾码|.NET、VUE快速搭建项目,低代码便捷开发教程
  • QML学习(五) 做出第一个简单的应用程序
  • 【Linux网络编程】第五弹---构建基于UDP的简单聊天室系统:代码结构与功能模块详解
  • 评分模型在路网通勤习惯分析中的应用——提出问题(1)
  • 【docker系列】创建博客 halo 2.11
  • 【yolov5】实现FPS游戏人物检测,并定位到矩形框上中部分,实现自瞄
  • 项目实践-贪吃蛇小游戏
  • 基于Resnet、LSTM、Shufflenet及CNN网络的Daily_and_Sports_Activities数据集仿真
  • 机器人骑自行车过程的MATLAB建模与数值仿真模拟
  • Linux之ARM(MX6U)裸机篇----1.开发环境搭建