mcpField
C
cpp

cpp

github.com/margelo开发179702 次安装10 周前更新
代码仓库

关于 cpp

面向 C++ 开发的编码技能,强调清晰的所有权、强类型建模、可维护的文件边界和可预测的原生集成,适用于原生代码及 Nitro Module 组件。

主要功能

  1. 01类型安全的状态建模
  2. 02RAII 与显式所有权指导
  3. 03异步与线程边界指导
  4. 04精简头文件并组织实现
  5. 05Nitro HybridObject 指导

适用场景

  1. 01建模原生 API 状态
  2. 02选择所有权与生命周期模式
  3. 03组织 C++ 实现及辅助代码
  4. 04实现 C++ Nitro 组件

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/margelo/react-native-skills --skill cpp

安装后在 Claude Code 中输入/cpp确认已加载。

附带文件agents/openai.yaml

详细介绍

C++

当 C++ 代码需要清晰的所有权关系、严谨的类型建模、易维护的文件边界和可预测的原生集成时,请使用此技能。如果代码属于 Nitro Module,请将此技能与 build-nitro-modules 搭配使用,以处理生成的规范、Promise 映射、CMake 和 HybridObject 约束。

工作流

  1. 编辑前,先阅读生成的头文件、公共 API 形态和本地所有权模式。
  2. 实现行为前,先用类型建模有效状态。
  3. 保持头文件小巧且稳定;将实现细节放入 .cpp 文件。
  4. 按职责拆分辅助代码,而不是不断扩充主要实现文件。
  5. 明确所有权、生命周期、线程和异步边界。

类型安全的 API 设计

  • 使用 std::variant、继承或独立的具体类型表示状态变体。不要用包含多个 std::optional 字段的单个结构体来编码变体。
  • 在变体中,相关值只要有效就应保持为非可选。如果 barcode 和 barcodeType 必须同时存在,就将它们都放在 ScannedBarcode 中。
  • 在同一状态内表示领域概念的真实缺失时,使用 std::optional;不要用它表示“此对象可能属于另一种类型”。
  • 优先采用编译期流程,而不是由调用方检查可选值。

文件组织

  • 将文件名视为作用域约定。HybridDataScanner.cpp 应实现 HybridDataScanner;不应同时定义无关的几何转换、UI 辅助代码、平台适配器或扩展式工具。
  • 默认每个文件只放一个主要类、一组相关结构体或一个内聚算法。将委托器、适配器、转换器、平台垫片和可复用辅助代码拆分到具名文件中,例如 GeometryConversions.cpp、DataScannerDelegate.cpp 或 PlatformViewController.cpp。
  • 仅当私有辅助代码较小且只服务于文件的主要类型时,才将其放入匿名命名空间。将可复用或较大的辅助代码移至独立文件,并放在 detail 命名空间或内部目录中。
  • 将行数作为代码审查的参考信号:低于约 300 行的文件通常没有问题;超过此范围的文件则需要有明确理由,且与单一内聚职责相关。因无关的辅助代码、转换或平台粘合代码导致文件变大,是设计问题。
  • 不要将大型实现主体藏在头文件中。头文件仅用于声明、必须可见的模板和小型内联函数。
  • 如果转换只读取一个元素,就将转换放在元素类型上,或为单个元素定义具名转换函数。单元素转换仍可返回多个值;调用方可使用标准循环、std::transform、插入集合或 std::accumulate 进行组合。
  • 仅当集合具有真实的领域行为时,才添加集合级辅助函数,例如跨元素验证、去重、排序、批处理、缓存、非空检查或错误聚合。

所有权与异步

  • 优先使用 RAII 和明确的所有权:使用值、std::unique_ptr;仅在确实需要共享生命周期时使用 std::shared_ptr。
  • 避免使用拥有所有权的裸指针。裸指针和引用应为非拥有型,并由周围的生命周期约定说明其有效期。
  • 使用 std::variant、std::optional 和强类型结构体表达 API 流程,而不是使用依赖字符串的状态。
  • 快速、确定性的本地工作保持同步。对于简单的值构造、缓存元数据或纯转换,不要引入执行器、promise 或回调机制。
  • 不要让调用方线程阻塞于 I/O、耗时的 CPU 工作或平台回调。可能需要等待时,使用项目的异步抽象、自有执行器/线程,或 Nitro Promise<T>。
  • 除非平台 API 有要求,否则避免使用平台主线程/UI 线程。主线程上的阻塞操作应尽可能少,并将解析、转换、I/O、会话协商和 CPU 工作移至自有执行器/线程或异步 API。
  • 将线程亲和状态置于明确的所有者之后。不要在缺少明确边界说明的情况下混用互斥锁、队列、回调和共享所有权。
  • 将重复的执行器、队列、线程或回调跳转视为架构异味。组件应自行拥有其工作所需的执行器/线程,或仅在公开的异步边界或原生回调边界跨入该所有者一次。
  • 如果工作流在多个嵌套位置来回切换平台、工作线程、JS/Nitro 和回调线程,请停下来重新设计对象/生命周期/API。过多的线程跳转会隐藏延迟、增加推理执行顺序的难度,并造成未来的性能问题。
  • 不要用 sleep_for、usleep、计时器、额外的执行器跳转或重复调用同一方法来修复竞态或就绪状态问题。应改为修复所有权、状态机、生命周期事件、回调约定或异步边界。仅针对硬件、OS 服务、远程服务或网络等外部不确定因素进行重试,并确保重试次数有限、可取消且幂等。
  • 将 std::mutex 视为最后手段,而非监听器或回调机制的默认选择。添加互斥锁前,先明确具体的共享可变值、并发调用方,以及为何单一所有者线程/队列、不可变快照或消息传递无法满足需求。
  • 调用回调、切入 JS/Nitro、调用可能发生未知重入的平台 API,或调用用户提供的代码时,绝不要持有互斥锁。先复制/快照分发所需的数据,再解锁并调用外部代码。

Nitro 说明

  • C++ HybridObject 必须继承生成的 Hybrid*Spec 类,并完全照抄生成的签名。
  • 为生成的异步方法使用 std::shared_ptr<Promise<T>>。
  • 生成的规范实现文件应专注于 HybridObject。将转换辅助函数、OpenCV 工具、平台适配器和仅供 CMake 使用的胶水代码放在单独文件中。
  • 在 JS 层使用的基础 HybridObject 应搭配原生接口或适配器类,以便 C++ 与由 Swift/Kotlin 支持的平台服务协作。

评论

支持 Markdown