关于 cpp
面向 C++ 开发的编码技能,强调清晰的所有权、强类型建模、可维护的文件边界和可预测的原生集成,适用于原生代码及 Nitro Module 组件。
主要功能
- 01类型安全的状态建模
- 02RAII 与显式所有权指导
- 03异步与线程边界指导
- 04精简头文件并组织实现
- 05Nitro HybridObject 指导
适用场景
- 01建模原生 API 状态
- 02选择所有权与生命周期模式
- 03组织 C++ 实现及辅助代码
- 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 约束。
工作流
- 编辑前,先阅读生成的头文件、公共 API 形态和本地所有权模式。
- 实现行为前,先用类型建模有效状态。
- 保持头文件小巧且稳定;将实现细节放入
.cpp文件。 - 按职责拆分辅助代码,而不是不断扩充主要实现文件。
- 明确所有权、生命周期、线程和异步边界。
类型安全的 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