C++ 基础思维导图(三)异常-STL

1、异常

异常举例

 BankAccount.h

#ifndef BANK_ACCOUNT_H
#define BANK_ACCOUNT_H

#include <iostream>
#include <stdexcept>

class InsufficientFundsException : public std::runtime_error {
public:
    InsufficientFundsException() : std::runtime_error("Insufficient funds for this operation.") {}
};

class BankAccount {
private:
    std::string accountNumber;
    double balance;

public:
    BankAccount(const std::string& accNum) : accountNumber(accNum), balance(0.0) {}

    void deposit(double amount) {
        if (amount <= 0) {
            throw std::invalid_argument("Deposit amount must be positive.");
        }
        balance += amount;
        std::cout << "Deposited: " << amount << ", New Balance: " << balance << std::endl;
    }

    void withdraw(double amount) {
        if (amount > balance) {
            throw InsufficientFundsException();
        }
        balance -= amount;
        std::cout << "Withdrew: " << amount << ", New Balance: " << balance << std::endl;
    }

    double getBalance() const {
        return balance;
    }

    std::string getAccountNumber() const {
        return accountNumber;
    }
};

#endif // BANK_ACCOUNT_H

  Bank.h

#ifndef BANK_H
#define BANK_H

#include <iostream>
#include <map>
#include "BankAccount.h"

class AccountNotFoundException : public std::runtime_error {
public:
    AccountNotFoundException(const std::string& accNum) 
        : std::runtime_error("Account not found: " + accNum) {}
};

class Bank {
private:
    std::map<std::string, BankAccount> accounts;

public:
    void createAccount(const std::string& accNum) {
        accounts.emplace(accNum, BankAccount(accNum));
        std::cout << "Account created: " << accNum << std::endl;
    }

    BankAccount& getAccount(const std::string& accNum) {
        auto it = accounts.find(accNum);
        if (it == accounts.end()) {
            throw AccountNotFoundException(accNum);
        }
        return it->second;
    }
};

#endif // BANK_H

main.cpp

#include <iostream>
#include "Bank.h"

int main() {
    Bank bank;

    try {
        bank.createAccount("12345");
        bank.createAccount("67890");

        // 存款
        bank.getAccount("12345").deposit(1000);
        bank.getAccount("67890").deposit(500);

        // 取款
        bank.getAccount("12345").withdraw(200);
        bank.getAccount("67890").withdraw(600); // 这将抛出异常

    } catch (const InsufficientFundsException& e) {
        std::cout << "Error: " << e.what() << std::endl;
    } catch (const AccountNotFoundException& e) {
        std::cout << "Error: " << e.what() << std::endl;
    } catch (const std::invalid_argument& e) {
        std::cout << "Error: " << e.what() << std::endl;
    } catch (const std::exception& e) {
        std::cout << "An unexpected error occurred: " << e.what() << std::endl;
    }

    return 0;
}

2、STL

 容器

int main() {
    //动态数组,支持随机访问,适合频繁插入和删除操作
    std::vector<int> vec = {1, 2, 3};
    vec.push_back(4); // 添加元素
    vec.insert(vec.begin() + 1, 5); // 在位置 1 插入 5
    vec.erase(vec.begin() + 2); // 删除位置 2 的元素
    //push_back():在末尾添加元素。pop_back():删除末尾元素。
    //erase():删除指定位置的元素. insert():在指定位置插入元素。
    for (int num : vec) {
        std::cout << num << " "; // 输出: 1 5 3 4
    }
    std::cout<<std::endl;
    //list 双向链表,适合频繁插入和删除操作,但不支持随机访问。
    //push_back():在末尾添加元素。push_front():在前面添加元素。
    //pop_back():删除末尾元素。pop_front():删除前面元素。
    std::list<int> lst = {1, 2, 3};
    lst.push_back(4); // 添加元素
    lst.push_front(0); // 在前面添加元素

    for (int num : lst) {
        std::cout << num << " "; // 输出: 0 1 2 3 4
    }
    std::cout<<std::endl;
    //deque:双端队列,支持在两端高效插入和删除
    //push_back():在末尾添加元素。push_front():在前面添加元素。
    //pop_back():删除末尾元素。 pop_front():删除前面元素
    std::deque<int> deq = {1, 2, 3};
    deq.push_back(4); // 添加元素
    deq.push_front(0); // 在前面添加元素
    for (int num : deq) {
        std::cout << num << " "; // 输出: 0 1 2 3 4
    }
    std::cout<<std::endl;
    //关联容器set 存储唯一元素自动排序,不支持重复元素
    //insert():添加元素。erase():删除元素。find():查找元素。
    std::set<int> s = {3, 1, 4, 1, 5}; // 1 会被忽略
    s.insert(2); // 添加元素
    for (int num : s) {
        std::cout << num << " "; // 输出: 1 2 3 4 5
    }
    std::cout<<std::endl;
    //关联容器map,存储键值对,键唯一自动排序
    //insert():添加键值对。erase():删除键值对。find():查找键对应的值。
    std::map<std::string, int> m;
    m["apple"] = 1;
    m["banana"] = 2;

    for (const auto& pair : m) {
        std::cout << pair.first << ": " << pair.second << std::endl; // 输出: apple: 1, banana: 2
    }
    //无序容器unordered_set无序容器不保证元素的顺序,主要用于快速查找
    std::unordered_set<int> us = {3, 1, 4, 1, 5}; // 1 会被忽略
    us.insert(2); // 添加元素
    for (int num : us) {
        std::cout << num << " "; // 输出顺序不确定
    }
    //unordered_map 存储键值对,不保证顺序。基于哈希表实现,查找效率高
    std::unordered_map<std::string, int> um;
    um["apple"] = 1;
    um["banana"] = 2;

    for (const auto& pair : um) {
        std::cout << pair.first << ": " << pair.second << std::endl; // 输出顺序不确定
    }
    return 0;
}

 迭代器

迭代器是一种对象,它提供了对容器中元素的访问方式。通过迭代器,用户可以遍历容器中的元素,而无需了解容器的内部实现细节。迭代器通常支持以下操作

解引用操作使用 * 运算符访问迭代器指向的元素
自增操作使用 ++ 运算符将迭代器移动到下一个元素
自减操作使用 -- 运算符将迭代器移动到前一个元素(适用于双向和随机访问迭代器)
比较操作使用 == 和 != 运算符比较两个迭代器是否相等

迭代器的类型 

输入迭代器只读访问元素,支持单向遍历。适用于只需要读取数据的场景
输出迭代器只写访问元素,支持单向遍历。适用于只需要写入数据的场景。
前向迭代器既可以读也可以写,支持单向遍历。可以多次遍历同一序列
双向迭代器既可以读也可以写,支持双向遍历。可以在两个方向上移动
随机访问迭代器既可以读也可以写,支持随机访问。可以直接访问容器中的任意元素
int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};
    // 使用迭代器遍历 vector
    for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); ++it) {
        std::cout << *it << " "; // 输出: 1 2 3 4 5
    }
    std::cout << std::endl;
    // 使用范围 for 循环
    for (const auto& num : vec) {
        std::cout << num << " "; // 输出: 1 2 3 4 5
    }
    //find算法查找
    auto it = std::find(vec.begin(), vec.end(), 3);
    
    if (it != vec.end()) {
        std::cout << "Found: " << *it << std::endl; // 输出: Found: 3
    } else {
        std::cout << "Not found" << std::endl;
    }
    std::vector<int> result(vec.size());
    //变换算法
    std::transform(vec.begin(), vec.end(), result.begin(), [](int x) { return x * 2; });

    for (const auto& num : result) {
        std::cout << num << " "; // 输出: 2 4 6 8 10
    }
     std::vector<int> destination(5);
    //copy 复制算法
    std::copy(vec.begin(), vec.end(), destination.begin());

    for (const auto& num : destination) {
        std::cout << num << " "; // 输出: 1 2 3 4 5
    }
    //删除元素
     std::vector<int> vec1 = {1, 2, 3, 2, 4, 2, 5};
    vec1.erase(std::remove(vec1.begin(), vec1.end(), 2), vec1.end()); // 删除所有 2

    for (const auto& num : vec1) {
        std::cout << num << " "; // 输出: 1 3 4 5
    }
    //聚合算法计算总和
    int sum = std::accumulate(vec.begin(), vec.end(), 0); // 计算总和

    std::cout << "Sum: " << sum << std::endl; // 输出: Sum: 15

    //集合算法,计算并集
    std::vector<int> vec1 = {1, 2, 3, 4};
    std::vector<int> vec2 = {3, 4, 5, 6};
    std::vector<int> result;
    std::set_union(vec1.begin(), vec1.end(), vec2.begin(), vec2.end(),
                   std::back_inserter(result)); // 计算并集

    for (const auto& num : result) {
        std::cout << num << " "; // 输出: 1 2 3 4 5 6
    }
    return 0;
}

适配器:

容器适配器:std::stack:基于底层容器(如 std::deque 或 std::vector)实现的后进先出(LIFO)数据结构。
std::queue:基于底层容器实现的先进先出(FIFO)数据结构。
std::priority_queue:基于底层容器实现的优先队列。

迭代器适配器:

常见的迭代器适配器有:std::reverse_iterator:反向迭代器,用于反向遍历容器。
std::insert_iterator:插入迭代器,用于在容器中插入元素。

函数对象适配器:常见的函数对象适配器有:std::negate:用于对值取反的函数对象。
std::not1 和 std::not2:用于对一元和二元函数对象取反。

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

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

相关文章

【C++入门】详解(中)

目录 &#x1f495;1.函数的重载 &#x1f495;2.引用的定义 &#x1f495;3.引用的一些常见问题 &#x1f495;4.引用——权限的放大/缩小/平移 &#x1f495;5. 不存在的空引用 &#x1f495;6.引用作为函数参数的速度之快&#xff08;代码体现&#xff09; &#x1f4…

人工智能之数学基础:函数间隔和几何间隔

本文重点 在机器学习领域,尤其是支持向量机(SVM)算法中,函数间隔(Functional Margin)和几何间隔(Geometric Margin)是两个至关重要的概念。它们不仅用于描述数据点到超平面的距离,还直接影响到分类器的性能与泛化能力。本文将详细介绍这两个概念,并探讨它们之间的区…

UE5 打包项目

UE5 打包项目 flyfish 通过 “文件”->“打开项目”&#xff0c;然后在弹出的对话框中选择项目文件&#xff08;通常是以.uproject为后缀的文件&#xff09; 选择目标平台&#xff1a; 在 UE5 主界面中&#xff0c;找到 “平台”&#xff08;Platforms&#xff09;。根据…

.NET framework、Core和Standard都是什么?

对于这些概念一直没有深入去理解&#xff0c;以至于经过.net这几年的发展进化&#xff0c;概念越来越多&#xff0c;越来越梳理不容易理解了。内心深处存在思想上的懒惰&#xff0c;以为自己专注于Unity开发就好&#xff0c;这些并不属于核心范畴&#xff0c;所以对这些概念总是…

《python》——jieba库

jieba库 jieba简介 jieba 是一个非常受欢迎的中文分词库 中文分词&#xff1a;这是 jieba 库最主要的功能。它能够将一段中文文本按照词语进行切分。例如&#xff0c;对于句子 “我爱自然语言处理”&#xff0c;jieba 分词后可以得到 [“我”, “爱”, “自然语言”, “处理”…

实训云上搭建集群

文章目录 1. 登录实训云1.1 实训云网址1.2 登录实训云 2. 创建网络2.1 网络概述2.2 创建步骤 3. 创建路由器3.1 路由器名称3.1 创建路由器3.3 查看网络拓扑 4. 连接子网5. 创建虚拟网卡5.1 创建原因5.2 查看端口5.3 创建虚拟网卡 6. 管理安全组规则6.1 为什么要管理安全组规则6…

python-42-使用selenium-wire爬取微信公众号下的所有文章列表

文章目录 1 seleniumwire1.1 selenium-wire简介1.2 获取请求和响应信息2 操作2.1 自动获取token和cookie和agent2.3 获取所有清单3 异常解决3.1 请求url失败的问题3.2 访问链接不安全的问题4 参考附录1 seleniumwire Selenium WebDriver本身并不直接提供获取HTTP请求头(header…

【理论】测试框架体系TDD、BDD、ATDD、MBT、DDT介绍

一、测试框架是什么 测试框架是一组用于创建和设计测试用例的指南或规则。框架由旨在帮助 QA 专业人员更有效地测试的实践和工具的组合组成。 这些指南可能包括编码标准、测试数据处理方法、对象存储库、存储测试结果的过程或有关如何访问外部资源的信息。 A testing framewo…

详细全面讲解C++中重载、隐藏、覆盖的区别

文章目录 总结1、重载示例代码特点1. 模板函数和非模板函数重载2. 重载示例与调用规则示例代码调用规则解释3. 特殊情况与注意事项二义性问题 函数特化与重载的交互 2. 函数隐藏&#xff08;Function Hiding&#xff09;概念示例代码特点 3. 函数覆盖&#xff08;重写&#xff…

计算机系统组成(计算机组成原理 基础)

文章目录&#xff1a; 一&#xff1a;体系结构 1.系统组成 1.1 硬件系统 1.2 软件系统 2.工作原理 2.1 冯诺依曼体系 2.2 指令和指令系统 3.性能指标 二&#xff1a;硬件系统 1.主机 1.1 CPU 1.2 内存 2.外设 2.1 外存 2.2 输入设备 2.3 输出设备 2.4 适配器 …

STM32 : 波特率发生器

波特率发生器 1. 发送器和接收器的波特率 波特率寄存器 (BRR): 在串行通信中&#xff0c;发送器和接收器的波特率是由波特率寄存器&#xff08;BRR&#xff09;中的一个值 DIV 来确定的。 2. 计算公式 计算公式: 详细解释 1. 波特率寄存器 (BRR) BRR: 波特率寄存器是一…

全新市场阶段, Plume 生态不断壮大的 RWAfi 版图

加密市场在 2024 年迎来了新的里程碑。BTC 不仅成功推出 ETF&#xff0c;以 BTC 为代表的主流加密货币还在一系列传统金融机构的推动下逐步与主流金融市场接轨。与此同时&#xff0c;随着特朗普成功当选下一任美国总统&#xff0c;他承诺推出一系列友好的加密政策&#xff0c;并…

MySQL的小问题

编码问题 不管官方使用什么编码&#xff1a;latin1、gbk、utf8、utfmb4。统一使用utfmb4 MySQL中的utf8并不是utf-8&#xff0c;它省略了一个字节&#xff0c;只是用三个字节存储所有的符号&#xff0c;utfmb4才是utf-8 远程登录问题&#xff1a; MySQL官方默认没有启动远程…

单片机(MCU)-简单认识

简介&#xff1a; 内部集成了CPU&#xff0c;RAM&#xff0c;ROM&#xff0c;定时器&#xff0c;中断系统&#xff0c;通讯接口等一系列电脑的常用硬件功能。 单片机的任务是信息采集&#xff08;依靠传感器&#xff09;&#xff0c;处理&#xff08;依靠CPU&#xff09;&…

金融项目实战 01|功能测试分析与设计

前置内容&#xff1a;金融项目准备的内容笔记可直接看如下笔记 只看&#xff1a;一、投资专业术语 和 二、项目简介 两部分文章浏览阅读2.3k次&#xff0c;点赞70次&#xff0c;收藏67次。安享智慧理财金融系统测试项目&#xff0c;测试用例&#xff0c;接口测试&#xff0c;金…

vue-cli项目配置使用unocss

在了解使用了Unocss后&#xff0c;就完全被它迷住了。接手过的所有项目都配置使用了它&#xff0c;包括一些旧项目&#xff0c;也跟同事分享了使用Unocss的便捷性。 这里分享一下旧项目如何配置和使用Unocss的&#xff0c;项目是vue2vue-cli构建的&#xff0c;node<20平常开…

5个不同类型的数据库安装

各种社区版本下载官方地址&#xff1a;MySQL :: MySQL Community Downloads 一、在线YUM仓库&#xff08;Linux&#xff09; 选择 MySQL Yum Repository 选择对应版本下载仓库安装包&#xff08;No thanks, just start my download.&#xff09; 下载方法1&#xff1a;下载到本…

《CPython Internals》阅读笔记:p97-p117

《CPython Internals》学习第 7 天&#xff0c;p97-p117 总结&#xff0c;总计 21 页。 一、技术总结 1.词法分析(lexical analysis) 根据《Compilers-Principles, Techniques, and Tools》(《编译原理》第2版)第 5 页&#xff1a;The first phase of a compiler is called …

js逆向说明

一 负载的内容传输用这个格式 Content-Type: multipart/form-data Content-Type 是 HTTP 请求头中的一个字段&#xff0c;它告诉服务器请求体的类型。在这个例子中&#xff0c;Content-Type 的值为 multipart/form-data&#xff0c;这表示请求体采用了 multipart/form-data 格…

什么是负载均衡?NGINX是如何实现负载均衡的?

大家好&#xff0c;我是锋哥。今天分享关于【什么是负载均衡&#xff1f;NGINX是如何实现负载均衡的&#xff1f;】面试题。希望对大家有帮助&#xff1b; 什么是负载均衡&#xff1f;NGINX是如何实现负载均衡的&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源…