跳到主要内容

C++98与C++11/14/17标准对比

一、C++标准演进历程

标准版本发布年份主要特性GCC支持
C++981998第一版C++标准GCC 3.x+
C++112011现代C++开端GCC 4.8+
C++142014C++11完善版GCC 5.x+
C++172017功能增强GCC 8.x+
C++202020重大更新GCC 10.x+

1.1 版本选择建议

# 根据项目需求选择
- 老项目维护:C++98 或 C++11
- 新项目开发:C++14 或 C++17
- 前沿探索:C++20

二、核心特性对比

2.1 类型推导

C++98

// 必须显式指定类型
std::vector<int>::iterator it = vec.begin();
const std::map<std::string, int>::value_type& val = *it;

C++11/14

// 自动类型推导
auto it = vec.begin(); // std::vector<int>::iterator
const auto& val = *it; // 推导为const引用

// C++14:返回类型推导
auto add(int a, int b) {
return a + b; // 推导为int
}

2.2 智能指针

C++98

// 手动内存管理
MyClass* obj = new MyClass();
try {
obj->doSomething();
delete obj;
} catch (...) {
delete obj;
throw;
}

C++11

// 智能指针自动管理
#include <memory>

std::unique_ptr<MyClass> obj = std::make_unique<MyClass>();
obj->doSomething(); // 自动释放

对比表

特性C++98C++11C++14
unique_ptr
shared_ptr
weak_ptr
make_shared
make_unique

2.3 Lambda表达式

C++98

// 使用函数对象
struct Printer {
void operator()(int x) {
std::cout << x << std::endl;
}
};

std::for_each(vec.begin(), vec.end(), Printer());

C++11/14

// Lambda表达式
std::for_each(vec.begin(), vec.end(), [](int x) {
std::cout << x << std::endl;
});

// C++14:泛型lambda
auto printer = [](auto x) {
std::cout << x << std::endl;
};

2.4 初始化语法

C++98

// 传统初始化
std::vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);

int arr[] = {1, 2, 3};

C++11

// 列表初始化
std::vector<int> v = {1, 2, 3};

// 统一初始化
int x{42};
std::vector<int> v2{1, 2, 3, 4};

// 防止窄化转换
int y{3.14}; // 编译错误

三、新增容器和算法

3.1 新增容器

C++11新增

#include <array>
#include <unordered_map>
#include <unordered_set>
#include <forward_list>

// array:固定大小数组
std::array<int, 5> arr = {1, 2, 3, 4, 5};

// unordered_map:哈希表
std::unordered_map<std::string, int> hashmap;
hashmap["apple"] = 10;

// forward_list:单向链表
std::forward_list<int> flist = {1, 2, 3};

容器对比

容器特点时间复杂度
std::array固定大小,栈上分配O(1)访问
std::vector动态数组O(1)访问,均摊O(1)插入
std::list双向链表O(n)访问,O(1)插入
std::forward_list单向链表O(n)访问,O(1)插入
std::deque双端队列O(1)访问两端
std::map红黑树O(log n)查找
std::unordered_map哈希表平均O(1)查找

3.2 新增算法

C++11新增算法

#include <algorithm>

// all_of, any_of, none_of
bool all_positive = std::all_of(v.begin(), v.end(),
[](int x) { return x > 0; });

// find_if_not
auto it = std::find_if_not(v.begin(), v.end(),
[](int x) { return x < 10; });

// copy_if
std::vector<int> result;
std::copy_if(src.begin(), src.end(),
std::back_inserter(result),
[](int x) { return x % 2 == 0; });

// move
std::vector<int> v2 = std::move(v1);

C++14新增

// equal, mismatch, is_permutation的谓词版本
auto eq = std::equal(v1.begin(), v1.end(),
v2.begin(), v2.end(),
[](int a, int b) { return a == b; });

四、并发支持

4.1 线程库

C++11

#include <thread>
#include <mutex>
#include <condition_variable>

// 创建线程
std::thread t([]() {
std::cout << "Hello from thread!" << std::endl;
});
t.join();

// 互斥锁
std::mutex mtx;
std::lock_guard<std::mutex> lock(mtx);
// 临界区代码

4.2 原子操作

C++11

#include <atomic>

std::atomic<int> counter(0);

// 原子递增
counter++;

// 原子读
int value = counter.load();

// 原子写
counter.store(42);

4.3 线程对比

特性POSIX线程 (C++98)C++11线程
创建方式pthread_createstd::thread
互斥锁pthread_mutexstd::mutex
条件变量pthread_condstd::condition_variable
跨平台Linux主要跨平台
类型安全

五、现代C++特性

5.1 右值引用和移动语义

C++11

// 移动构造函数
class MyClass {
std::vector<int> data;
public:
// 移动构造函数
MyClass(MyClass&& other) noexcept
: data(std::move(other.data)) {}

// 移动赋值运算符
MyClass& operator=(MyClass&& other) noexcept {
if (this != &other) {
data = std::move(other.data);
}
return *this;
}
};

// 使用移动语义
std::vector<MyClass> v;
v.push_back(MyClass()); // 移动而非拷贝

5.2 constexpr

C++11

// 编译期常量表达式
constexpr int square(int x) {
return x * x;
}

constexpr int result = square(5); // 编译期计算

C++14

// C++14:更宽松的constexpr
constexpr int factorial(int n) {
int result = 1;
for (int i = 1; i <= n; ++i) {
result *= i;
}
return result;
}

5.3 可变参数模板

C++11

// 可变参数模板
template<typename... Args>
void printAll(Args... args) {
(std::cout << ... << args) << std::endl; // C++17折叠表达式
}

// 使用
printAll(1, "hello", 3.14);

六、代码风格迁移

6.1 推荐使用

// ✅ 现代 C++11/14
auto vec = std::vector<int>{1, 2, 3};
auto ptr = std::make_unique<MyClass>();
for (const auto& item : vec) {
std::cout << item << std::endl;
}

6.2 避免使用

// ❌ C++98 风格
std::vector<int> vec;
vec.push_back(1);
vec.push_back(2);

for (size_t i = 0; i < vec.size(); ++i) {
std::cout << vec[i] << std::endl;
}

七、编译器支持

7.1 GCC版本支持

GCC版本C++98C++11C++14C++17C++20
GCC 4.8⚠️
GCC 5.x⚠️
GCC 8.x⚠️
GCC 10.x
GCC 12.x

7.2 编译选项

# C++98
g++ -std=c++98 file.cpp

# C++11
g++ -std=c++11 file.cpp

# C++14
g++ -std=c++14 file.cpp

# C++17
g++ -std=c++17 file.cpp

# C++20
g++ -std=c++20 file.cpp

八、总结

8.1 核心差异

方面C++98C++11/14/17
类型安全⚠️
内存管理手动智能
并程支持第三方内置
性能基准优化
开发效率中等

8.2 迁移建议

老项目 → 逐步迁移

1. 使用智能指针替代原始指针
2. 使用auto简化代码
3. 使用range-based for循环
4. 使用lambda表达式
5. 使用现代容器和算法

8.3 最佳实践

  • ✅ 新项目优先使用C++14或C++17
  • ✅ 使用智能指针管理资源
  • ✅ 使用RAII模式
  • ✅ 使用STL容器和算法
  • ✅ 使用constexpr提高性能
  • ⚠️ 注意ABI兼容性问题
  • ⚠️ 老项目谨慎升级