Skip to content

Ch 1: Python 程序员为什么需要学 C++

  • 理解 Python 和 C++ 的核心差异
  • 明白什么时候该选择 C++ 而不是 Python
  • 了解 C++ 的学习路径和本书的结构
  • 掌握 Python 与 C++ 互补的设计理念

Python 是当今最流行的编程语言之一,尤其在数据科学、Web 开发、人工智能等领域占据主导地位。它的设计哲学强调开发效率和可读性,让程序员能够用更少的代码表达更多的想法。

Python 的核心优势:

# 1. 简洁的语法
# Python 代码行数通常是 C++ 的 1/3 到 1/5
def quicksort(arr):
return [] if not arr else quicksort([x for x in arr[1:] if x < arr[0]]) + \
[arr[0]] + \
quicksort([x for x in arr[1:] if x >= arr[0]])
# 2. 丰富的标准库
import json
import asyncio
import http.server
from collections import defaultdict
from typing import List, Dict
# 3. 强大的第三方生态
# pip install numpy pandas torch transformers
import numpy as np
import torch

但 Python 有明显的性能天花板。当处理以下场景时,Python 的速度可能成为瓶颈:

# Python - CPU 密集型任务
import time
def matrix_multiply(a, b):
"""朴素矩阵乘法 - O(n³)"""
n = len(a)
result = [[0.0] * n for _ in range(n)]
for i in range(n):
for j in range(n):
for k in range(n):
result[i][j] += a[i][k] * b[k][j]
return result
# 测试 200x200 矩阵乘法
a = [[i * j for j in range(200)] for i in range(200)]
b = [[i + j for j in range(200)] for i in range(200)]
start = time.time()
result = matrix_multiply(a, b)
elapsed = time.time() - start
print(f"Python time: {elapsed:.2f}s") # 可能需要 5-10 秒
// C++ - 同一算法的优化版本
#include <vector>
#include <chrono>
#include <iostream>
std::vector<std::vector<double>> matrix_multiply(
const std::vector<std::vector<double>>& a,
const std::vector<std::vector<double>>& b) {
size_t n = a.size();
std::vector<std::vector<double>> result(n, std::vector<double>(n, 0.0));
for (size_t i = 0; i < n; ++i) {
for (size_t k = 0; k < n; ++k) {
// 循环重排:提高缓存命中率
for (size_t j = 0; j < n; ++j) {
result[i][j] += a[i][k] * b[k][j];
}
}
}
return result;
}
int main() {
size_t n = 200;
std::vector<std::vector<double>> a(n, std::vector<double>(n));
std::vector<std::vector<double>> b(n, std::vector<double>(n));
// 初始化
for (size_t i = 0; i < n; ++i) {
for (size_t j = 0; j < n; ++j) {
a[i][j] = i * j;
b[i][j] = i + j;
}
}
auto start = std::chrono::high_resolution_clock::now();
auto result = matrix_multiply(a, b);
auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration<double>(end - start);
std::cout << "C++ time: " << duration.count() << "s" << std::endl;
return 0;
}

性能差异可达 50-500 倍。原因:

  • Python 每次循环迭代都有 Python 对象创建/销毁开销
  • C++ 编译后直接是 CPU 指令
  • C++ 编译器可以进行自动向量化优化
  • C++ 内存布局紧凑,缓存命中率高
# Python - 每个整数都是完整的 Python 对象
import sys
# Python int 对象:28 字节(64位)
x = 42
print(sys.getsizeof(x)) # 28 bytes
# 列表中的每个元素都是指针
arr = [1, 2, 3, 4, 5]
# 实际内存:5 * 28 (int对象) + 5 * 8 (指针) + list开销 ≈ 180 bytes
// C++ - int 就是 4 字节
#include <iostream>
int main() {
int x = 42;
std::cout << sizeof(x) << std::endl; // 4 bytes
// vector 中的 int 是连续内存
std::vector<int> arr = {1, 2, 3, 4, 5};
// 实际内存:5 * 4 = 20 bytes
}

理解两者的核心差异,有助于在合适的时候选择合适的工具:

Python - 动态类型(Duck Typing):

# Python - 类型在运行时决定
def add(a, b):
return a + b # 只有运行时才知道 a + b 是什么操作
add(1, 2) # int.__add__ → 3
add("hello", " world") # str.__add__ → "hello world"
add([1, 2], [3, 4]) # list.__add__ → [1, 2, 3, 4]
add(1, "hello") # TypeError at runtime!

C++ - 静态类型(编译时确定):

// C++ - 类型在编译时就确定
template<typename T>
T add(T a, T b) {
return a + b; // 编译时验证 T 支持 +
}
add(1, 2); // OK: int 支持 +
add(std::string("hello"), std::string(" world")); // OK: string 支持 +
add(1, std::string("hello")); // 编译错误!类型不匹配

Python - 自动垃圾回收:

import gc
class Data:
def __init__(self, value):
self.value = value
print(f"Data({value}) created")
def __del__(self):
print(f"Data({self.value}) destroyed")
# Python GC 处理内存
d = Data(42)
d = None # 引用计数归零,立即回收
# 循环引用 - GC 处理
a = Data(1)
b = Data(2)
a.ref = b
b.ref = a
del a
del b
# GC 会检测并清理循环引用

C++ - 手动+RAII:

#include <memory>
#include <iostream>
class Data {
public:
int value;
Data(int v) : value(v) {
std::cout << "Data(" << value << ") created" << std::endl;
}
~Data() {
std::cout << "Data(" << value << ") destroyed" << std::endl;
}
};
// 手动管理
void manual() {
Data* d = new Data(42);
delete d; // 必须手动释放
}
// 智能指针 - RAII 方式
void smart() {
auto d = std::make_unique<Data>(42);
// 无需手动 delete,退出作用域自动释放
}
int main() {
smart(); // Data(42) created, Data(42) destroyed
return 0;
}
维度PythonC++
编译解释执行(字节码)编译为机器码
类型检查运行时编译时
内存管理GC 自动回收手动 + RAII
并发模型GIL 限制真并行原生多线程
编译单元.py 文件.cpp + .h
构建时间无(解释器即时)较长
运行时间较慢极快

选择 C++ 当你需要:

// 游戏引擎 - 每帧需要数百万次计算
class PhysicsEngine {
std::vector<RigidBody> bodies;
void simulate(float dt) {
// 物理模拟必须 60fps
for (auto& body : bodies) {
body.applyForce(gravity);
body.integrate(dt); // 数千个物体的积分
body.checkCollisions(bodies); // 碰撞检测
}
}
};
// 音视频编解码 - 实时处理
void encode_frame(const Frame& frame, Encoder& enc) {
// 1080p 60fps = 每帧约 16ms
enc.dct(frame); // 离散余弦变换
enc.quantize(); // 量化
enc.entropy_encode(); // 熵编码
}
// 高频交易 - 微秒级延迟
class OrderRouter {
std::chrono::high_resolution_clock::time_point send_time;
void send_order(const Order& order) {
send_time = std::chrono::high_resolution_clock::now();
network_.send(order); // 直接发送,无 GC 暂停
}
void on_ack() {
auto latency = std::chrono::high_resolution_clock::now() - send_time;
// 目标是 < 10 微秒
}
};
// 嵌入式 - 有限内存
class SensorDriver {
// 目标:单片机 2KB RAM
static constexpr size_t BUFFER_SIZE = 64;
uint8_t buffer_[BUFFER_SIZE]; // 栈上分配,无动态内存
public:
void read() {
// 没有 malloc/new,全部栈分配
// 没有异常,没有 STL(可配置)
}
};
# 业务逻辑 - Python 更高效
def process_order(order):
# 数据库操作
db.save(order)
# 发送通知
notification.send(order.customer_email)
# 业务规则
if order.total > 1000:
apply_discount(order)
return order.confirmation
# Web 开发 - Django/Flask + C++ 扩展
# 用 Python 写业务逻辑,热点用 C++ 扩展
# 数据科学 - NumPy/Pandas(底层 C)
import pandas as pd
df = pd.read_csv("data.csv")
df.groupby("category").mean() # 底层 C 实现,极快
# 机器学习 - PyTorch(底层 C++ CUDA)
import torch
model = torch.nn.Linear(784, 10) # CUDA 加速

1.4.1 零成本抽象(Zero-Cost Abstraction)

Section titled “1.4.1 零成本抽象(Zero-Cost Abstraction)”

C++ 的核心理念:不为你不使用的东西付出代价

# Python - 列表推导有运行时开销
squares = [x**2 for x in range(1000000)]
# 内存:创建新列表对象
# CPU:Python 解释器逐个执行
// C++ 范围 for - 编译后等价于指针遍历
std::vector<int> v(1000000);
for (int x : v) { // 编译后:就是指针遍历,无迭代器开销
process(x);
}
// 内存:不创建新容器
// CPU:编译优化后就是裸指针遍历
# Python - 错误在运行时发现
def get_nested(data):
return data["key"]["nested"] # 如果 data 或 data["key"] 不存在
# 运行到这行才知道出错
# TypeError: 'NoneType' object is not subscriptable
// C++ - 错误在编译时发现(如果可能)
std::optional<std::unordered_map<std::string, std::string>> get_data() {
return std::nullopt;
}
// 编译通过,但运行时会抛出异常
// std::cout << get_data().value().at("key") << std::endl;
// 安全的写法 - 编译器强制你检查
if (auto opt = get_data()) {
std::cout << opt->at("key") << std::endl; // 安全
}
# Python - 需要上下文管理器确保清理
class DatabaseConnection:
def __init__(self, conn_str):
self.conn = create_connection(conn_str)
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.conn.close() # with 块退出时调用
# 使用
with DatabaseConnection("connection_string") as db:
db.execute("SELECT * FROM users")
# 离开 with 块时自动关闭连接
// C++ - RAII 自动管理
class DatabaseConnection {
public:
DatabaseConnection(const std::string& conn_str) {
conn_ = create_connection(conn_str);
}
~DatabaseConnection() {
conn_.close(); // 析构函数自动关闭
}
void execute(const std::string& sql) { /* ... */ }
private:
Connection conn_;
};
// 使用 - 无需显式关闭
void query() {
DatabaseConnection db("connection_string");
db.execute("SELECT * FROM users");
} // db 析构函数自动调用,连接关闭
Part I: 入门与环境
├── ch01: 为什么学 C++(你在这里)
├── ch02: C++ 的哲学和权衡
├── ch03: 开发环境搭建
├── ch04: 第一个 C++ 程序
├── ch05: 变量和类型基础
└── ch06: auto 和类型推导
Part II: 基础语法
├── ch07: 基本类型(int、float、char、bool)
├── ch08: 字符串和格式化
├── ch09: 控制流(if、switch)
├── ch10: 循环和迭代
Part III: 标准容器
├── ch14: std::vector
├── ch15: std::unordered_map
├── ch16: std::tuple 和 std::optional
├── ch17: std::array 和容器选择
└── ch18: 迭代器和算法
Part IV: 函数
├── ch11: 函数基础
├── ch12: 函数高级(重载、默认参数、递归)
└── ch13: Lambda 和 std::function
Part V: 面向对象
├── ch19: 类基础
├── ch20: 构造和析构函数
├── ch21: 继承和多态
└── ch22: 运算符重载
Part VI: 内存管理
├── ch23: 智能指针
├── ch24: 移动语义
└── ch25: RAII 和内存
Part VII: C++20 现代特性
├── ch26: Concepts 约束
├── ch27: Ranges 库
└── ch28: C++20 新特性
Part VIII: 实战
├── ch29: 错误处理
└── ch30: CLI 任务管理器项目
  • 变量、类型、函数
  • 控制流、循环
  • 基本容器(vector、string)
  • 类和对象
  • 构造/析构函数
  • 继承和多态
  • 内存管理(智能指针)
  • C++20 新特性
  • 标准库算法
  • 完成 CLI 任务管理器项目
  • 阅读优秀 C++ 开源代码

误解 1:C++ 很难学

实际上,现代 C++(C++11 以后)简化了很多。Python 开发者可以直接学习 C++20,不需要从 C++98 开始。

// C++20 - 像 Python 一样简洁
std::vector<int> v = {1, 2, 3, 4, 5};
auto filtered = v | std::views::filter([](int x) { return x % 2 == 0; })
| std::views::transform([](int x) { return x * x; });

误解 2:C++ 容易出错

C++ 确实需要更仔细,但 RAII、智能指针、modern C++ guidelines 大幅降低了出错概率。

误解 3:Python 永远比 C++ 慢

NumPy、Pandas、PyTorch 底层都是 C++。Python 代码调用这些库时,实际执行的是 C++ 代码。

  • Python 和 C++ 是互补的语言,各有擅长的领域
  • C++ 提供极致性能和精细控制,代价是更复杂的语法和更长的编译时间
  • 选择合适工具解决问题,而不是盲目追求性能
  • 现代 C++(C++11/14/17/20)大幅简化了代码,更容易学习
  • RAII 和智能指针让 C++ 内存管理比以往安全得多

下章预告:ch02 深入探讨 C++ 的哲学理念,理解零成本抽象和现代 C++ 的设计思想。