文章目录

C++ 基础速通给前端与 Electron 开发者

适合目标:让前端或 Electron 开发者快速补齐 Native Addon 开发必需的 C++ 基础,不追求纯 C++ 岗位深度,但要做到能读 SDK、能封装接口、能排查常见问题。
学习重点:变量与类型、指针与引用、类与对象、内存管理、RAII、智能指针、STL、异常与错误码、线程基础。
学习原则:只学 Electron 调 C++ 真正要用到的部分,先打通概念,再结合 Native Addon 场景理解。


目录

  1. 学习总览
  2. 前端为什么要补 C++
  3. C++ 基础语法
  4. 指针、引用与 const
  5. 类、对象、构造与析构
  6. 内存管理
  7. RAII 与智能指针
  8. STL 常用容器
  9. 字符串与二进制数据
  10. 错误处理
  11. 线程与并发基础
  12. 头文件、编译与链接
  13. 面向 Electron 的 C++ 实战心智
  14. 高频面试题
  15. 一页速记总结
  16. 背诵口诀

1. 学习总览

1.1 前端学 C++ 最容易掉进的误区

很多前端同学学 C++ 时会出现两种偏差:

  1. 要么一上来就学很多语法细节,结果和 Electron 实战脱节
  2. 要么只会照着示例改代码,但完全不理解内存和生命周期

如果你的目标是 Electron 调 C++,真正最重要的是:

  1. 能看懂 SDK 文档和头文件
  2. 能写简单封装
  3. 能管理对象生命周期
  4. 能理解线程和阻塞问题
  5. 能把 C++ 数据转换给 JS

1.2 学习优先级

优先级建议:

  1. 指针 / 引用 / const
  2. 类 / 对象 / 构造析构
  3. 内存管理
  4. RAII / 智能指针
  5. std::string / std::vector
  6. 线程基础
  7. 错误处理

2. 前端为什么要补 C++

2.1 在 Electron 场景里最常遇到的真实任务

  1. 封装设备 SDK
  2. 调 C 接口或 C++ 类库
  3. 把原生结果转成 JS 字符串、对象或 Buffer
  4. 在原生层开线程做耗时任务
  5. 排查崩溃、内存泄漏、卡顿

2.2 只懂 JavaScript 为什么不够

因为原生侧很多问题都不是 JS 维度:

  1. 指针悬空
  2. 内存泄漏
  3. 线程竞争
  4. 动态库加载失败
  5. 编译和链接错误

3. C++ 基础语法

3.1 变量与类型

常见基础类型:

  1. int
  2. double
  3. bool
  4. char
  5. std::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;
}

你要熟悉:

  1. 参数
  2. 返回值
  3. 重载

3.3 命名空间

namespace device {
  int open() {
    return 0;
  }
}

作用:

  1. 避免命名冲突
  2. 按模块组织代码

4. 指针、引用与 const

这一节是前端最容易卡住的。

4.1 指针是什么

指针本质上存的是内存地址。

int x = 10;
int* p = &x;

这里:

  1. x 是变量
  2. &xx 的地址
  3. p 存的是这个地址

通过 *p 可以取到地址指向的值。

4.2 引用是什么

引用可以理解成变量的别名。

int x = 10;
int& ref = x;
ref = 20;

修改 ref,本质上就是修改 x

4.3 指针和引用区别

  1. 指针可以为空
  2. 引用通常必须绑定到一个对象
  3. 指针更灵活,引用更安全直观

4.4 const

const 表示只读约束。

const int x = 10;

在 Electron 开发里,要重点理解:

  1. const std::string&
  2. const char*
  3. const 成员函数

4.5 为什么这块重要

因为 Native Addon 里你经常会看到:

  1. 传引用避免拷贝
  2. 用指针管理底层对象
  3. 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++ 时,析构函数经常承担:

  1. 关闭设备句柄
  2. 释放内存
  3. 关闭文件
  4. 清理线程资源

如果析构没设计好,很容易:

  1. 内存泄漏
  2. 资源未释放
  3. 程序退出异常

6. 内存管理

6.1 栈和堆

  1. 生命周期自动管理
  2. 速度快

  1. 手动申请
  2. 手动释放
  3. 更灵活但更危险

6.2 new 和 delete

int* p = new int(5);
delete p;

6.3 常见坑

  1. 忘记 delete
  2. 重复 delete
  3. delete[]delete 混用
  4. 用完后继续访问

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>();

特点:

  1. 更安全
  2. 生命周期清晰
  3. 推荐优先使用

7.3 shared_ptr

共享所有权。

std::shared_ptr<Device> device = std::make_shared<Device>();

适合多个对象共同持有。

7.4 对 Electron 开发的建议

默认优先:

  1. 栈对象
  2. unique_ptr
  3. 必要时才 shared_ptr

不要动不动裸 new / delete


8. STL 常用容器

8.1 std::string

最常用字符串类型。

8.2 std::vector

动态数组。

std::vector<int> nums = {1, 2, 3};

在原生开发里经常用来:

  1. 存二进制数据
  2. 存结果列表
  3. 作为中间缓冲区

8.3 std::map / unordered_map

键值映射。

8.4 为什么 STL 很重要

因为很多 SDK 封装和 Node-API 转换都需要先用 STL 容器整理数据。


9. 字符串与二进制数据

9.1 字符串

要注意:

  1. UTF-8
  2. 宽字符
  3. 平台编码差异

9.2 Buffer / 二进制

Electron 场景里很常见:

  1. 图片字节流
  2. 音频 PCM 数据
  3. 串口协议包
  4. 厂商 SDK 返回的 raw bytes

所以你要理解:

  1. 内存归谁管
  2. 是否会发生拷贝
  3. 何时释放

10. 错误处理

10.1 错误码风格

很多 C SDK 会返回:

  1. 0 表示成功
  2. 0 表示错误

10.2 异常风格

现代 C++ 常用异常,但很多底层库不会这么设计。

10.3 实战建议

对 Electron 项目最好的做法是:

  1. 原生层内部统一错误风格
  2. 向 JS 暴露统一错误对象
  3. 保留错误码和错误消息

11. 线程与并发基础

11.1 为什么必须懂线程

因为:

  1. 硬件调用可能阻塞
  2. 图像处理可能耗时
  3. AI 推理可能耗时
  4. 不能堵住 Electron 主线程

11.2 你至少要懂的概念

  1. 主线程
  2. 工作线程
  3. 互斥锁
  4. 临界区
  5. 线程安全

11.3 面向 Electron 的线程原则

  1. 重活放后台线程
  2. 不要跨线程乱操作 JS 对象
  3. 生命周期要清晰

12. 头文件、编译与链接

12.1 头文件和实现文件

常见形式:

  1. .h / .hpp
  2. .cc / .cpp

头文件放声明,实现文件放具体实现。

12.2 编译和链接怎么理解

编译

把源代码变成目标文件。

链接

把多个目标文件和库拼起来,生成最终产物。

12.3 为什么 Electron 原生开发经常遇到链接错误

因为你经常要链接:

  1. 第三方 SDK
  2. 系统动态库
  3. Node / Electron 相关头文件

13. 面向 Electron 的 C++ 实战心智

13.1 不要把 C++ 层写成“大业务层”

C++ 更适合做:

  1. 性能敏感逻辑
  2. SDK 封装
  3. 数据转换
  4. 原生能力适配

不适合把复杂业务流程全搬进去。

13.2 优先做薄封装

建议:

  1. 原生层越薄越好
  2. 业务编排尽量留在 JS / TS
  3. 页面只看稳定 API

13.3 重点关注生命周期

每写一个原生对象都问自己:

  1. 谁创建
  2. 谁持有
  3. 谁释放
  4. 何时释放

14. 高频面试题

14.1 指针和引用区别

  1. 指针存地址,可以为空
  2. 引用是别名,通常必须绑定对象

14.2 构造函数和析构函数作用

构造负责初始化,析构负责释放资源。

14.3 为什么要用智能指针

为了减少内存泄漏和手动管理错误。

14.4 为什么 Electron 开发要理解线程

因为原生耗时任务如果堵住主线程,会导致应用卡顿和无响应。


15. 一页速记总结

15.1 够用的 C++ 能力清单

  1. 指针 / 引用
  2. 类 / 对象 / 析构
  3. 内存管理
  4. RAII / 智能指针
  5. STL 容器
  6. 线程基础

15.2 记忆口诀

先懂对象生命周期,再谈封装和性能;优先 RAII 和智能指针,少写裸 new/delete。


16. 背诵口诀

前端补 C++,重点不在花哨语法,在生命周期、内存、线程和封装能力。