楼层: 首页/ 软件技术/ 现代 C++/ 标准库进阶:string、时间、随机、包装类型
库

标准库进阶:string、时间、随机、包装类型

String · chrono · random · optional/variant

这一章把第 10 章提到的几个现代库真正用起来。它们不性感,但每天都在用。看完你就明白:为什么现代 C++ 程序里几乎看不到 malloc 和 char 数组了。

std::string 的常用操作

拼接、查找、截取、转数字

#include <string> #include <iostream> std::string s = "hello"; s += " world"; // 拼接,变成 "hello world" auto pos = s.find("world"); // 找子串,返回位置;找不到返回 npos std::string sub = s.substr(0, 5); // 从 0 取 5 个字符:"hello" int n = std::stoi("123"); // 字符串转 int;stod 转 double std::string back = std::to_string(3.14); // 数字转回字符串

std::optional:可能没值

以前查不到就返回 -1 或空指针,调用者很容易忘判断。std::optional 把"有没有值"直接写进类型里。

用 optional 表示"可能查不到"

#include <optional> #include <map> // 查成绩:查到返回分数,查不到返回 std::nullopt std::optional<double> lookup(const std::map<std::string,double>& db, const std::string& name) { auto it = db.find(name); if (it == db.end()) return std::nullopt; // 没有值 return it->second; } // 调用者必须显式处理"没有"的情况 auto r = lookup(db, "小明"); if (r) std::cout << "成绩:" << *r; // 有值才解引用 else std::cout << "没这个人";

variant / any / tuple:能装多种类型

类型(C++17)大白话
variant<int,double>一个变量"是 int 或 是 double",但同一时刻只能是其中一种,类型安全。
any能装任意一种类型的盒子,取出时要指定类型。
tuple<int,string,double>打包多个不同类型的值,配合结构化绑定解包。

tuple + 结构化绑定

#include <tuple> // 一个函数想同时返回三个值,用 tuple 打包 auto get_user() { return std::make_tuple(std::string("小明"), 18, 92.5); } auto [name, age, score] = get_user(); // 一次解开三个值

时间与随机数

chrono 计时 + mt19937 真随机

#include <chrono> #include <random> // 计时:测一段代码跑了多久 auto t0 = std::chrono::steady_clock::now(); // ... 干点活 ... auto t1 = std::chrono::steady_clock::now(); double ms = std::chrono::duration<double, std::milli>(t1 - t0).count(); // 随机数:mt19937 比老 rand() 均匀、可播种 std::mt19937 rng(std::random_device{}()); std::uniform_int_distribution<int> dice(1, 6); int roll = dice(rng); // 掷骰子 1~6

构建工具:CMake

C++ 项目跨平台、依赖多,手写 Makefile 扛不住。CMake 是事实标准——写一份 CMakeLists.txt,它帮你生成 Makefile 或 VS 工程。最小骨架:

CMakeLists.txt

cmake_minimum_required(VERSION 3.20) project(MyApp CXX) set(CMAKE_CXX_STANDARD 20) # 用 C++20 add_executable(app main.cpp task.cpp) # 把这些源文件编成 app

用法

$ cmake -B build # 生成构建文件 $ cmake --build build # 编译 $ ./build/app

学习资源(都能白嫖)

资源特点适合阶段
cppreference.comC++ 标准库权威手册,每个类都有例子,必备书签。查 API,随手翻
C++ Core GuidelinesC++ 之父本人牵头的编码规范,讲"为什么这么写"。入门后精读
Compiler Explorer(godbolt)实时看代码变汇编、看 RVO/移动怎么生效。学移动语义时
《Effective Modern C++》Scott Meyers 写现代 C++ 的 42 条军规,经典。有基础后进阶

五个最常用设计模式:会这几个就够日常

设计模式不是八股,是"别人踩过坑总结出的沟通语言"。C++ 面试和工程里出现频率最高的五个,挨个说人话:

模式解决什么问题(人话)
单例 Singleton全程序只有一个实例(配置对象、日志器)。懒汉式 + 互斥锁线程安全。注意:现代 C++ 也常用"命名空间里的全局函数 + 局部静态变量"代替。
工厂 Factorynew 一个对象时不想写死具体类。给一个参数,工厂返回"该类型的对象",方便以后加新品种不改调用方。
观察者 Observer"发布-订阅":一放多。被观察的数据变了,所有订阅者自动收到通知。Qt 的 signal/slot、事件回调都是它。
策略 Strategy同一类行为有多种算法可换(排序策略、打折方式)。把算法抽成可替换对象,运行时切换。STL 算法传入不同 lambda 就是策略思想。
装饰器 Decorator不修改原类,用"层层包装"给对象加功能(咖啡加奶加糖)。C++ 的 std::shared_ptr 包装原始指针、IO 流套 stream 就是装饰器。

单例(Meyers' Singleton,C++11 起线程安全)最常用写法

class Config { public: static Config& instance() { static Config inst; // 局部静态变量:第一次调用时构造,C++11 保证线程安全 return inst; } // 禁止拷贝和赋值,保证只有一个 Config(const Config&) = delete; Config& operator=(const Config&) = delete; private: Config() = default; // 构造私有,外面 new 不了 }; // 用法:Config::instance().load("app.cfg");

建议:别为了用模式而用模式。先写直白代码,当发现"这里改来改去""要插新分支"时,再回头套对应模式——模式是给"变化点"做隔离的,不是默认框架。