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:用于对一元和二元函数对象取反。