SUNKAIS OS · READ ONLY

Jarvis

登录后,可以询问自己的任务、项目和记录。

登录后使用
Sun KaisPersonal Research Institute · 私人研究机构

Mathematics · Computational Science · Engineering · Personal Knowledge Systems

更多
SUNKAIS · PERSONAL OS

搜索全站功能

选择 前往

LANG-02 · PROGRAMMING WORKBENCH

C++

用 RAII、值语义和泛型算法构建高性能且边界清晰的软件。

从标准库容器与算法进入现代 C++,用 CMake、测试和 Sanitizer 把复杂性约束在可验证的工程边界内。

MENTAL MODEL / 心智模型

先建立正确的程序直觉

优先值语义与确定性析构:对象离开作用域时自动释放资源,裸指针通常只表达非拥有观察。

CODE REPOSITORY / 代码仓库锚点

从可测试的目录开始

cpp-project/
├─ CMakeLists.txt
├─ include/app/model.hpp
├─ src/main.cpp
├─ src/model.cpp
└─ tests/model_test.cpp

QUICK START / 第一条命令

先跑通最小闭环

c++ -std=c++20 -Wall -Wextra -Wpedantic -g src/main.cpp -o build/app

LEARNING ROUTE / 学习路径

从写出代码到守住生产边界

每个节点都包含可复制示例、判断原则与常见陷阱。

01常用方法容器、算法与错误返回02工程结构接口、实现与 target03构建运行工具链与构建配置04依赖管理包与第三方库05调试测试测试、静态分析与调试06错误诊断模板、链接与生命周期错误07安全边界所有权、边界与并发安全
01常用方法

容器、算法与错误返回

优先使用标准库抽象,让边界与所有权由类型表达。

范围算法代码示例
std::vector<int> values{4, 1, 7, 1};
std::ranges::sort(values);
auto unique_end = std::ranges::unique(values).begin();
values.erase(unique_end, values.end());

算法表达意图;删除重复项仍需配合容器 erase。

可选结果代码示例
std::optional<User> find_user(std::string_view id);

if (auto user = find_user(input)) {
    render(*user);
}

用 optional 表达“可能没有值”,不要用魔法哨兵值。

RAII 文件资源代码示例
std::ifstream input(path);
if (!input) {
    throw std::runtime_error("cannot open input");
}
std::string line;
while (std::getline(input, line)) { process(line); }

流对象析构时自动关闭文件;构造成功后资源与对象生命周期绑定。

02工程结构

接口、实现与 target

减少头文件耦合,把编译选项和依赖绑定到明确 target。

窄接口代码示例
#pragma once
#include <span>

namespace app {
double mean(std::span<const double> values);
}

span 表达连续的非拥有视图,并携带长度;头文件只 include 契约所需内容。

现代 CMake代码示例
cmake_minimum_required(VERSION 3.20)
project(model_lab LANGUAGES CXX)
add_library(model src/model.cpp)
target_include_directories(model PUBLIC include)
target_compile_features(model PUBLIC cxx_std_20)
add_executable(app src/main.cpp)
target_link_libraries(app PRIVATE model)

PUBLIC/PRIVATE 描述依赖是否传播,避免 directory 级全局设置。

03构建运行

工具链与构建配置

保持编译数据库、调试符号和可切换配置,让 IDE 与命令行使用同一事实来源。

配置与构建终端命令
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
cmake --build build
ctest --test-dir build --output-on-failure

单配置生成器使用 CMAKE_BUILD_TYPE;Visual Studio 等多配置生成器用 --config。

严格单文件编译终端命令
c++ -std=c++20 -Wall -Wextra -Wpedantic -Wconversion -g src/main.cpp -o build/app

适合最小实验;正式工程将选项放到 CMake target。

Sanitizer 构建终端命令
c++ -std=c++20 -fsanitize=address,undefined -fno-omit-frame-pointer -g src/main.cpp -o build/app

平台支持不同;MSVC 可使用其 AddressSanitizer 配置。

04依赖管理

包与第三方库

使用清单锁定依赖,优先链接导入 target,避免复制二进制与 include 路径。

vcpkg manifest代码示例
{
  "name": "model-lab",
  "version-string": "0.1.0",
  "dependencies": ["fmt", "catch2"]
}

manifest 模式让依赖与工程一起版本化;baseline 用于锁定解析版本。

链接导入 target代码示例
find_package(fmt CONFIG REQUIRED)
target_link_libraries(app PRIVATE fmt::fmt)

不要手工拼接库文件路径;导入 target 会携带传递依赖与平台设置。

05调试测试

测试、静态分析与调试

把崩溃复现成最小测试,再用调用栈、Sanitizer 和静态分析交叉定位。

标准库断言测试代码示例
#include <cassert>

int main() {
    assert(mean(std::array{2.0, 4.0, 6.0}) == 4.0);
}

快速实验可用 assert;持续集成更适合 Catch2、GoogleTest 等测试框架。

GDB / LLDB 轨迹终端命令
break main
run
bt
frame 0
print object

先看线程与调用栈,再检查对象生命周期、容器状态和动态类型。

静态分析终端命令
clang-tidy src/model.cpp -- -std=c++20 -Iinclude

最好让 clang-tidy 读取 compile_commands.json,确保分析参数与真实构建一致。

06错误诊断

模板、链接与生命周期错误

先识别错误阶段,再从第一条真正错误向上追踪。

模板报错过长诊断清单
定位最早出现的 required from / constraints not satisfied;缩小模板实参,检查 concept、const 和引用限定。

后续数十条通常是级联错误;不要从日志末尾开始读。

undefined reference诊断清单
检查实现是否链接、命名空间/const/noexcept/模板签名是否一致,以及模板定义是否对实例化点可见。

这是链接错误,不是 include 数量不足的同义词。

迭代器失效诊断清单
核对容器操作的失效规则;vector 扩容、erase 和 reallocation 后不要继续使用旧迭代器、指针或引用。

优先保存索引或重新获取迭代器,并写覆盖边界的测试。

07安全边界

所有权、边界与并发安全

让类型表达所有权和范围,把裸 new/delete 与无界访问赶出业务代码。

独占所有权代码示例
auto model = std::make_unique<Model>(config);
run(*model);

默认用 unique_ptr;只有确实共享生命周期时才考虑 shared_ptr。

边界可见的输入代码示例
double mean(std::span<const double> values) {
    if (values.empty()) throw std::invalid_argument("empty input");
    return std::reduce(values.begin(), values.end()) / values.size();
}

span 携带长度但不拥有数据;调用者仍需保证底层对象存活。

并发清单诊断清单
共享可变状态最小化;用锁或消息传递建立同步;用 ThreadSanitizer 检查数据竞争;不要跨锁调用未知回调。

volatile 不能替代原子或互斥同步。

PRIVATE CODE VAULT / 私人代码仓库

C++ 私人代码与伪代码仓库

把 C++ 的练习、工程片段、算法伪代码、验证说明与历史版本保存在登录后的私人空间。

TEXT ONLYRLS PRIVATENO EXECUTION
这里只归档,不运行代码。支持导入与下载纯文本源码;`.mlx`、`.xlsx`、`.accdb` 等二进制容器不会入库。密码、Token、私钥等秘密也会被拒绝,请改用环境变量。
PRIVATE SESSION REQUIRED

登录后打开你的私人仓库

游客只看到这个说明,不会收到、缓存或渲染任何私人源码。

安全登录

REFERENCE SOURCES / 官方与高质量资料

版本差异优先以官方文档为准

先在本站找回路径,再进入原始文档确认版本、平台和完整前置条件。

DELIVERY LOOP / 练习闭环

把每次练习变成可以重新运行的资产

  1. 01 · 定义写清输入、输出、边界与失败行为。
  2. 02 · 最小实现先让单一案例从命令行完整运行。
  3. 03 · 验证增加边界测试、调试信息与质量检查。
  4. 04 · 沉淀提交代码、README、依赖清单和复现命令。