【C++ 笔记】从 C 到 C++:核心过渡
这是一篇系统、实用的过渡指南,帮助熟悉 C 语言的开发者快速掌握 C++ 的核心差异与现代特性。C++ 被誉为“带类的 C”(C with Classes),它几乎完全兼容 C(C++ 是 C 的超集),但新增了面向对象(OOP)、泛型编程、更强的类型安全和现代标准库,让代码更安全、更优雅、更易维护,同时保留 C 的高效与底层控制力。
C++ 不是“换个语法”的 C,而是多范式语言(过程式 + OOP + 泛型 + 函数式)。建议:先把 C++ 当作“更好的 C”来用,逐步引入新特性。
1. 为什么从 C 过渡到 C++?
- 兼容性:绝大多数合法 C 代码可直接作为 C++ 编译(用
g++编译.c文件也行,但推荐后缀.cpp)。 - 优势:
- 更严格的类型检查(减少隐式转换错误)。
- 自动内存管理机制(RAII)。
- 标准库(STL)极大提升生产力。
- 支持大型项目维护(封装、继承、多态)。
- 适用场景:系统编程、游戏引擎、嵌入式、高性能计算、竞赛编程等。C 更适合极致轻量或纯过程式场景。
编译器推荐:GCC/Clang(g++ -std=c++20)、MSVC。现代 C++ 强烈建议用 C++17 或 C++20 标准。
2. 第一个程序:Hello World 对比
C 风格(兼容):
#include <stdio.h>
int main() {
printf("Hello, World!\n");
return 0;
}
C++ 现代风格:
#include <iostream>
int main() {
std::cout << "Hello, World!" << std::endl;
return 0;
}
差异:
- 头文件:C 用
<stdio.h>,C++ 推荐<iostream>(无.h)。 - 输入输出:
printf/scanf→std::cout/cin(自动类型推导,支持运算符重载)。 std::命名空间:避免全局命名冲突。
使用命名空间简化:
using namespace std; // 不推荐在头文件中使用
cout << "Hello" << endl;
3. 核心语法与特性差异(C → C++)
(1) 输入输出与命名空间(Namespace)
- C 无命名空间,容易全局冲突。
- C++ 用
namespace解决:
namespace MySpace {
int x = 10;
void func() {}
}
// 使用方式
MySpace::x; // 指定访问
using MySpace::func; // 部分展开
using namespace MySpace; // 全部展开(小心冲突)
(2) 函数增强
- 默认参数(Default Arguments):
void print(int a, int b = 0) { // b 默认值为 0
// ...
}
print(5); // 等价于 print(5, 0)
注意:默认参数必须从右到左连续定义。
- 函数重载(Overloading):
同名函数,参数个数/类型/顺序不同(返回值不影响):
void func(int x) {}
void func(double x) {}
void func(int x, int y) {}
- inline 函数:建议编译器内联展开,减少函数调用开销(C99 也有,但 C++ 更常用)。
- 引用(Reference):
&别名,更安全替代指针。
void swap(int& a, int& b) { // 传引用,无需指针
int temp = a; a = b; b = temp;
}
(3) 类型系统与常量
- bool 类型:C++ 原生
true/false,C 中常用int。 - nullptr:代替 C 的
NULL(避免宏问题)。 - const:C++ 中
const更严格,常用于常量表达式。 - 类型别名:
typedef→using(C++11,更灵活):
using ll = long long;
(4) 内存管理
- C:
malloc/calloc/realloc/free(不调用构造函数)。 - C++:
new/delete(自动调用构造函数/析构函数)。
int* p = new int(10); // 初始化
delete p;
int* arr = new int[5]{}; // 数组 + 值初始化
delete[] arr;
现代 C++ 强烈推荐:智能指针(RAII,避免内存泄漏):
#include <memory>
std::unique_ptr<int> up = std::make_unique<int>(42);
std::shared_ptr<int> sp = std::make_shared<int>(100);
(5) 结构体 vs 类(Class)
- C:
struct仅数据成员。 - C++:
struct/class几乎相同(默认访问权限不同:struct public,class private)。
支持封装、构造函数/析构函数、成员函数:
class Point {
private:
int x, y;
public:
Point(int a = 0, int b = 0) : x(a), y(b) {} // 构造函数
~Point() {} // 析构函数
void show() const { /* ... */ }
};
核心 OOP:
- 封装(private/protected/public)
- 继承(
class Derived : public Base) - 多态(虚函数
virtual+ 重写overrideC++11)
(6) 其他重要差异
- 类型转换:C++ 更安全(
static_cast、dynamic_cast、const_cast、reinterpret_cast)。 - void* 指针:C++ 不能隐式转换为其他指针类型(更严格)。
- 枚举:C++11
enum class(强类型枚举)。 - 初始化:C++ 支持列表初始化
{}(uniform initialization,C++11)。
4. 现代 C++ 核心特性(C++11 及以后)——“新语言”级提升
C++11 被誉为“现代 C++”起点,后续 C++14/17/20/23 持续演进:
- auto 类型推导:
auto x = 5; // int
auto v = std::vector<int>{1,2,3};
- 范围 for 循环(Range-based for):
for (auto& elem : vec) { /* ... */ }
- Lambda 表达式(匿名函数):
auto add = [](int a, int b) { return a + b; };
std::sort(vec.begin(), vec.end(), [](int a, int b){ return a > b; });
- 移动语义(Move Semantics)+ 右值引用
&&:高效转移资源,避免不必要拷贝。 - 智能指针、
std::array、std::tuple等。 - constexpr:编译期计算。
- 线程支持(
<thread>)、原子操作、异常处理(try/catch)。
STL 容器与算法(远超 C 的手动实现):
std::vector(动态数组)、std::string、std::map、std::unordered_map等。- 算法:
std::sort、std::find、std::accumulate。
5. 最佳实践与注意事项(过渡期避坑)
- 从“更好 C”开始:先用
cout、vector、string,再学类。 - 避免:裸
new/delete(用智能指针)、全局using namespace std;(头文件)、C 风格数组(优先std::array或vector)。 - 性能:C++ 零开销抽象(Zero-overhead principle),用好 RAII 和移动语义可比 C 更快。
- 编译选项:
-std=c++20 -Wall -Wextra -O2。 - 常见错误:
- 忘记
delete[]或析构函数。 - 隐式转换导致 bug(C++ 更严格)。
- 多线程下共享数据未同步。
- 自定义类型作为 key:需重载
operator<或提供哈希函数。
6. 学习路径建议
- 掌握基础过渡(本笔记内容)→ 写小项目(如学生管理系统)。
- 深入 OOP + STL。
- 现代 C++:读《Effective Modern C++》、《C++ Primer》(第 5 版及以后)。
- 实践:LeetCode(C++)、实现简单数据结构、贡献开源。
- 进阶:模板元编程、并发、C++20 模块(Modules)、协程、Ranges。
通过以上过渡,你会发现 C++ 代码更简洁、安全,且在大型项目中维护性远超纯 C。C++ 不是取代 C,而是让 C 程序员拥有更强大的武器。
如果需要具体章节扩展(如类与继承详解、STL 容器对比、现代 C++11/14/17/20 特性代码示例、或某个项目的完整过渡案例),随时告诉我!加油,掌握 C++ 后,你的编程视野会打开新世界。🚀
(参考常见 C/C++ 对比资料与现代标准演进,实践时以编译器实际行为为准。)