这片土地的旧时光 · 详解 C++98 与新版 C++ 的不同
C++ 是一门历史悠久的语言。从 1983 年 Bjarne Stroustrup 发明它开始,到 1998 年 ISO 正式标准化(C++98),再到如今的 C++23,这门语言经历了翻天覆地的变化。
如果你曾经接触过老派的 C++ 教材,或者维护过年代久远的代码库,可能会发现它们与现代 C++ 有着天壤之别。让我们来看看,这片土地上发生过怎样的沧桑巨变。
内存管理的进化
在 C++98 时代,动态内存管理是一场噩梦:
// C++98 风格:手动管理内存
class OldStyle
{
int* data;
public:
OldStyle() : data(new int[100]) {}
~OldStyle() { delete[] data; }
// 必须手动实现拷贝构造和赋值,否则会 double free!
OldStyle(const OldStyle& other) : data(new int[100])
{
for (int i = 0; i < 100; ++i)
data[i] = other.data[i];
}
OldStyle& operator=(const OldStyle& other)
{
if (this != &other)
{
delete[] data;
data = new int[100];
for (int i = 0; i < 100; ++i)
data[i] = other.data[i];
}
return *this;
}
};现代 C++ 使用智能指针,一切变得简单:
auto_ptr 的消亡
C++98 有一个叫 auto_ptr 的智能指针,但它有严重的设计缺陷:
C++11 废弃了 auto_ptr,引入了语义清晰的智能指针家族:
类型推断的革命
C++98 要求显式写出所有类型:
C++11 引入 auto 关键字,代码变得简洁:
初始化的统一
C++98 的初始化方式混乱不堪:
C++11 统一使用花括号初始化:
范围 for 循环
遍历容器在 C++98 中很繁琐:
C++11 的范围 for 循环简洁明了:
nullptr 的引入
C++98 使用 NULL 或 0 表示空指针,这会导致重载歧义:
C++11 引入类型安全的 nullptr:
移动语义的诞生
C++98 没有移动语义,复制临时对象非常低效:
C++11 的移动语义避免了不必要的复制:
Lambda 表达式
C++98 需要为每个简单操作定义函数对象:
C++11 的 lambda 让一切变得简单:
constexpr:编译期计算
C++98 的编译期计算只能通过模板元编程:
C++11/14 的 constexpr 让编译期计算变得自然:
变参模板
C++98 处理可变数量参数非常困难:
C++11 的变参模板优雅地解决了这个问题:
总结:旧时光与新纪元
内存管理
new/delete 手动管理
智能指针自动管理
类型声明
完全手写
auto 自动推断
空指针
NULL 或 0
nullptr
初始化
多种语法
统一的 {} 语法
循环
迭代器
范围 for
函数对象
手写类
lambda 表达式
编译期计算
模板元编程
constexpr
移动语义
无
右值引用
现代 C++ 不仅仅是语法上的改进,更是编程理念的革新。它让 C++ 从一门"专家语言"变成了一门更加安全、高效、易用的语言。
如果你还在使用 C++98 风格编程,是时候拥抱现代 C++ 了!
Last updated