C++ 基础速通给前端与 Electron 开发者
适合目标:让前端或 Electron 开发者快速补齐 Native Addon 开发必需的 C++ 基础,不追求纯 C++ 岗位深度,但要做到能读 SDK、能封装接口、能排查常见问题。
学习重点:变量与类型、指针与引用、类与对象、内存管理、RAII、智能指针、STL、异常与错误码、线程基础。
学习原则:只学 Electron 调 C++ 真正要用到的部分,先打通概念,再结合 Native Addon 场景理解。
目录
- 学习总览
- 前端为什么要补 C++
- C++ 基础语法
- 指针、引用与 const
- 类、对象、构造与析构
- 内存管理
- RAII 与智能指针
- STL 常用容器
- 字符串与二进制数据
- 错误处理
- 线程与并发基础
- 头文件、编译与链接
- 面向 Electron 的 C++ 实战心智
- 高频面试题
- 一页速记总结
- 背诵口诀
1. 学习总览
1.1 前端学 C++ 最容易掉进的误区
很多前端同学学 C++ 时会出现两种偏差:
- 要么一上来就学很多语法细节,结果和 Electron 实战脱节
- 要么只会照着示例改代码,但完全不理解内存和生命周期
如果你的目标是 Electron 调 C++,真正最重要的是:
- 能看懂 SDK 文档和头文件
- 能写简单封装
- 能管理对象生命周期
- 能理解线程和阻塞问题
- 能把 C++ 数据转换给 JS
1.2 学习优先级
优先级建议:
- 指针 / 引用 / const
- 类 / 对象 / 构造析构
- 内存管理
- RAII / 智能指针
std::string/std::vector- 线程基础
- 错误处理
2. 前端为什么要补 C++
2.1 在 Electron 场景里最常遇到的真实任务
- 封装设备 SDK
- 调 C 接口或 C++ 类库
- 把原生结果转成 JS 字符串、对象或 Buffer
- 在原生层开线程做耗时任务
- 排查崩溃、内存泄漏、卡顿
2.2 只懂 JavaScript 为什么不够
因为原生侧很多问题都不是 JS 维度:
- 指针悬空
- 内存泄漏
- 线程竞争
- 动态库加载失败
- 编译和链接错误
3. C++ 基础语法
3.1 变量与类型
常见基础类型:
intdoubleboolcharstd::string
示例:
int age = 18;
double score = 99.5;
bool ok = true;
std::string name = "electron";
3.2 函数
int add(int a, int b) {
return a + b;
}
你要熟悉:
- 参数
- 返回值
- 重载
3.3 命名空间
namespace device {
int open() {
return 0;
}
}
作用:
- 避免命名冲突
- 按模块组织代码
4. 指针、引用与 const
这一节是前端最容易卡住的。
4.1 指针是什么
指针本质上存的是内存地址。
int x = 10;
int* p = &x;
这里:
x是变量&x是x的地址p存的是这个地址
通过 *p 可以取到地址指向的值。
4.2 引用是什么
引用可以理解成变量的别名。
int x = 10;
int& ref = x;
ref = 20;
修改 ref,本质上就是修改 x。
4.3 指针和引用区别
- 指针可以为空
- 引用通常必须绑定到一个对象
- 指针更灵活,引用更安全直观
4.4 const
const 表示只读约束。
const int x = 10;
在 Electron 开发里,要重点理解:
const std::string&const char*const成员函数
4.5 为什么这块重要
因为 Native Addon 里你经常会看到:
- 传引用避免拷贝
- 用指针管理底层对象
- 用
const表达只读语义
5. 类、对象、构造与析构
5.1 类和对象
class Device {
public:
int open() {
return 0;
}
};
Device d;
5.2 构造函数
对象创建时执行。
class Device {
public:
Device() {}
};
5.3 析构函数
对象销毁时执行。
class Device {
public:
~Device() {}
};
5.4 为什么析构非常重要
在 Electron 调 C++ 时,析构函数经常承担:
- 关闭设备句柄
- 释放内存
- 关闭文件
- 清理线程资源
如果析构没设计好,很容易:
- 内存泄漏
- 资源未释放
- 程序退出异常
6. 内存管理
6.1 栈和堆
栈
- 生命周期自动管理
- 速度快
堆
- 手动申请
- 手动释放
- 更灵活但更危险
6.2 new 和 delete
int* p = new int(5);
delete p;
6.3 常见坑
- 忘记
delete - 重复
delete delete[]和delete混用- 用完后继续访问
6.4 为什么前端特别容易栽在这里
因为 JS 有 GC,而 C++ 很多资源需要你显式管理。
7. RAII 与智能指针
这部分是写可靠 C++ 的关键。
7.1 RAII 是什么
RAII 可以理解成:
资源在对象构造时获取,在对象析构时释放。
这样可以减少忘记释放资源的风险。
7.2 unique_ptr
独占所有权。
std::unique_ptr<Device> device = std::make_unique<Device>();
特点:
- 更安全
- 生命周期清晰
- 推荐优先使用
7.3 shared_ptr
共享所有权。
std::shared_ptr<Device> device = std::make_shared<Device>();
适合多个对象共同持有。
7.4 对 Electron 开发的建议
默认优先:
- 栈对象
unique_ptr- 必要时才
shared_ptr
不要动不动裸 new / delete。
8. STL 常用容器
8.1 std::string
最常用字符串类型。
8.2 std::vector
动态数组。
std::vector<int> nums = {1, 2, 3};
在原生开发里经常用来:
- 存二进制数据
- 存结果列表
- 作为中间缓冲区
8.3 std::map / unordered_map
键值映射。
8.4 为什么 STL 很重要
因为很多 SDK 封装和 Node-API 转换都需要先用 STL 容器整理数据。
9. 字符串与二进制数据
9.1 字符串
要注意:
- UTF-8
- 宽字符
- 平台编码差异
9.2 Buffer / 二进制
Electron 场景里很常见:
- 图片字节流
- 音频 PCM 数据
- 串口协议包
- 厂商 SDK 返回的 raw bytes
所以你要理解:
- 内存归谁管
- 是否会发生拷贝
- 何时释放
10. 错误处理
10.1 错误码风格
很多 C SDK 会返回:
0表示成功- 非
0表示错误
10.2 异常风格
现代 C++ 常用异常,但很多底层库不会这么设计。
10.3 实战建议
对 Electron 项目最好的做法是:
- 原生层内部统一错误风格
- 向 JS 暴露统一错误对象
- 保留错误码和错误消息
11. 线程与并发基础
11.1 为什么必须懂线程
因为:
- 硬件调用可能阻塞
- 图像处理可能耗时
- AI 推理可能耗时
- 不能堵住 Electron 主线程
11.2 你至少要懂的概念
- 主线程
- 工作线程
- 互斥锁
- 临界区
- 线程安全
11.3 面向 Electron 的线程原则
- 重活放后台线程
- 不要跨线程乱操作 JS 对象
- 生命周期要清晰
12. 头文件、编译与链接
12.1 头文件和实现文件
常见形式:
.h/.hpp.cc/.cpp
头文件放声明,实现文件放具体实现。
12.2 编译和链接怎么理解
编译
把源代码变成目标文件。
链接
把多个目标文件和库拼起来,生成最终产物。
12.3 为什么 Electron 原生开发经常遇到链接错误
因为你经常要链接:
- 第三方 SDK
- 系统动态库
- Node / Electron 相关头文件
13. 面向 Electron 的 C++ 实战心智
13.1 不要把 C++ 层写成“大业务层”
C++ 更适合做:
- 性能敏感逻辑
- SDK 封装
- 数据转换
- 原生能力适配
不适合把复杂业务流程全搬进去。
13.2 优先做薄封装
建议:
- 原生层越薄越好
- 业务编排尽量留在 JS / TS
- 页面只看稳定 API
13.3 重点关注生命周期
每写一个原生对象都问自己:
- 谁创建
- 谁持有
- 谁释放
- 何时释放
14. 高频面试题
14.1 指针和引用区别
- 指针存地址,可以为空
- 引用是别名,通常必须绑定对象
14.2 构造函数和析构函数作用
构造负责初始化,析构负责释放资源。
14.3 为什么要用智能指针
为了减少内存泄漏和手动管理错误。
14.4 为什么 Electron 开发要理解线程
因为原生耗时任务如果堵住主线程,会导致应用卡顿和无响应。
15. 一页速记总结
15.1 够用的 C++ 能力清单
- 指针 / 引用
- 类 / 对象 / 析构
- 内存管理
- RAII / 智能指针
- STL 容器
- 线程基础
15.2 记忆口诀
先懂对象生命周期,再谈封装和性能;优先 RAII 和智能指针,少写裸 new/delete。
16. 背诵口诀
前端补 C++,重点不在花哨语法,在生命周期、内存、线程和封装能力。