C++11 让 C++ 从“老派系统语言”转变为“现代高效安全的多范式语言”
C++11 是 C++ 语言历史上一次重大更新,于 2011 年正式发布(ISO/IEC 14882:2011),引入了大量新特性,极大提升了语言的表达力、安全性、性能和现代编程能力。以下是对 C++11 新增标准 的全面详细总结,并附带典型使用示例代码。
一、核心目标
C++11 的设计目标包括:
-
提高类型安全
-
提升性能(尤其是多线程和零开销抽象)
-
增强泛型编程能力
-
改善代码可读性与简洁性
-
支持现代硬件(如多核)
二、主要新增特性分类总结
1. 语言核心特性
(1) 自动类型推导:auto
auto x = 42; // int
auto y = 3.14; // double
auto s = "hello"; // const char*
auto lambda = [](int n){ return n * 2; };
✅ 避免冗长类型声明,提升泛型代码可维护性。
(2) 范围 for 循环(Range-based for)
std::vector<int> v = {1, 2, 3, 4};
for (auto& elem : v) {
elem *= 2;
}
for (const auto& e : v) {
std::cout << e << " ";
}
支持任何提供 begin() / end() 的容器(包括数组)。
(3) 初始化列表(Initializer List)
std::vector<int> v = {1, 2, 3}; // 使用 std::initializer_list<int>
std::map<std::string, int> m = {{"a", 1}, {"b", 2}};
// 自定义类支持
class MyContainer {
public:
MyContainer(std::initializer_list<int> list) {
for (auto x : list) data.push_back(x);
}
private:
std::vector<int> data;
};
MyContainer c = {1, 2, 3, 4};
(4) 统一初始化(Uniform Initialization)与 {} 语法
int a{5}; // 直接初始化
std::vector<int> v{1,2,3};
std::complex<double> c{3.0, 4.0};
// 防止“最 vexing parse”问题
Widget w1(10); // 可能被解析为函数声明!
Widget w2{10}; // 明确是对象构造
(5) nullptr(空指针字面量)
替代 NULL(本质是 0),解决重载歧义:
void foo(int);
void foo(char*);
foo(0); // 调用 foo(int)
foo(NULL); // 仍可能调用 foo(int)(因 NULL == 0)
foo(nullptr); // 明确调用 foo(char*)
类型:std::nullptr_t
(6) constexpr(编译期常量表达式)
constexpr int square(int x) {
return x * x;
}
constexpr int val = square(5); // 编译期计算
// C++11 中限制较多(只能单 return,无循环等)
允许在编译期求值,用于模板参数、数组大小等。
(7) 委托构造函数(Delegating Constructors)
class MyClass {
public:
MyClass() : MyClass(42) {} // 委托给另一个构造函数
MyClass(int value) : data(value) {}
private:
int data;
};
(8) 继承构造函数(Inheriting Constructors)
struct Base {
Base(int x) {}
};
struct Derived : Base {
using Base::Base; // 继承 Base 的所有构造函数
};
(9) 强类型枚举(enum class)
enum class Color { Red, Green, Blue };
Color c = Color::Red;
// 不会隐式转换为 int,避免命名污染
(10) override 与 final
struct Base {
virtual void foo() {}
virtual void bar() final {} // 不能被 override
};
struct Derived : Base {
void foo() override {} // 明确表示覆盖
// void bar() override {} // 编译错误!
};
提高虚函数重写的正确性和可读性。
(11) 右值引用与移动语义(Rvalue References & Move Semantics)
核心:T&&,支持资源转移而非深拷贝。
class MyString {
char* data;
public:
// 移动构造函数
MyString(MyString&& other) noexcept
: data(other.data) {
other.data = nullptr; // “偷”资源
}
// 移动赋值
MyString& operator=(MyString&& other) noexcept {
if (this != &other) {
delete[] data;
data = other.data;
other.data = nullptr;
}
return *this;
}
};
std::vector<MyString> vec;
vec.push_back(MyString("temp")); // 触发 move,避免拷贝
配合 std::move() 使用:
MyString a("hello");
MyString b = std::move(a); // a 现在处于有效但未指定状态
(12) 完美转发(Perfect Forwarding)与 std::forward
template<typename T>
void wrapper(T&& arg) {
foo(std::forward<T>(arg)); // 保持原始值类别(左值/右值)
}
依赖引用折叠规则和universal reference(T&& 在模板中)。
2. 标准库增强
(1) 智能指针(Smart Pointers)
std::unique_ptr:独占所有权,轻量,不可复制
std::shared_ptr:共享所有权,引用计数
std::weak_ptr:解决
shared_ptr循环引用
auto p1 = std::make_unique<MyClass>(); // C++14 推荐,但 C++11 可手写
auto p2 = std::make_shared<int>(42);
std::weak_ptr<int> wp = p2; // 不增加引用计数
if (auto sp = wp.lock()) {
std::cout << *sp;
}
✅ 避免裸
new/delete,实现 RAII。
(2) Lambda 表达式
auto add = [](int a, int b) { return a + b; };
std::cout << add(2, 3); // 5
// 捕获变量
int factor = 2;
auto scale = [factor](int x) { return x * factor; }; // 值捕获
auto scale_ref = [&factor](int x) { return x * factor; }; // 引用捕获
// mutable 允许修改副本
auto f = [x = 5]() mutable { x++; return x; };
极大简化 STL 算法使用:
std::vector<int> v = {3, 1, 4, 1, 5};
std::sort(v.begin(), v.end(), [](int a, int b) { return a > b; });
(3) 线程支持库(<thread>)
#include <thread>
#include <mutex>
std::mutex mtx;
void worker(int id) {
std::lock_guard<std::mutex> lock(mtx);
std::cout << "Thread " << id << "\n";
}
int main() {
std::thread t1(worker, 1);
std::thread t2(worker, 2);
t1.join();
t2.join();
}
其他组件:
std::async,
std::future,std::promisestd::condition_variable-
原子操作
<atomic>
(4) 新容器与工具
std::array<T, N>:固定大小数组,替代 C 风格数组
std::forward_list:单向链表
std::unordered_map/
std::unordered_set:基于哈希表std::tuple:多类型元组
std::array<int, 3> arr = {1, 2, 3};
auto t = std::make_tuple(42, "hello", 3.14);
int a; const char* b; double c;
std::tie(a, b, c) = t;
(5) std::function 与 std::bind
#include <functional>
std::function<int(int, int)> f = [](int a, int b) { return a + b; };
std::cout << f(2, 3); // 5
// bind 示例
void print(int a, int b) { std::cout << a << ", " << b; }
auto g = std::bind(print, std::placeholders::_1, 10);
g(5); // 输出 "5, 10"
(6) decltype
推导表达式类型:
int x = 0;
decltype(x) y = x; // y is int
decltype((x)) z = x; // z is int& (因为 (x) 是左值)
// 用于返回类型后置
template<typename T, typename U>
auto add(T a, U b) -> decltype(a + b) {
return a + b;
}
(7) 返回类型后置(Trailing Return Type)
template<typename T, typename U>
auto multiply(T a, U b) -> decltype(a * b) {
return a * b;
}
在 C++11 中常用于模板函数返回类型依赖参数的情况。
3. 其他重要特性
(1) static_assert(编译期断言)
template<typename T>
void foo() {
static_assert(sizeof(T) <= 8, "Type too large!");
}
(2) 属性(Attributes)初步支持(如 [[noreturn]])
[[noreturn]] void die() {
throw std::runtime_error("Fatal");
}
(3) 对齐控制(alignas, alignof)
alignas(16) char buffer[128];
std::cout << alignof(double); // 输出 double 的对齐要求
(4) noexcept 异常规范
void foo() noexcept { /* 不抛异常 */ }
// 移动操作通常标记为 noexcept
MyClass(MyClass&&) noexcept;
影响编译器优化和 std::vector 是否使用 move。
三、弃用或移除的特性(C++11)
auto_ptr(被
unique_ptr替代)-
注册关键字
register(仍保留但无作用) -
动态异常规范(如
throw(int))被弃用,推荐noexcept
四、总结:C++11 带来的范式转变
|
领域 |
C++03 |
C++11 |
|---|---|---|
|
内存管理 |
手动 new/delete |
智能指针 + RAII |
|
并发 |
依赖平台(如 pthread) |
标准线程库 |
|
泛型编程 |
复杂模板技巧 |
auto
+ |
|
性能 |
拷贝开销大 |
移动语义 + 完美转发 |
|
代码简洁性 |
冗长 |
范围 for、统一初始化、lambda |
五、推荐实践
- 优先使用
auto(除非需要显式类型转换)
- 用
{}初始化代替() - 用
nullptr代替NULL或0 - 资源管理用智能指针,避免裸指针
- 移动语义用于高性能容器和返回值优化
- lambda 简化算法和回调
- 多线程使用标准库,避免平台相关 API
✅ 一句话总结:
C++11 让 C++ 从“老派系统语言”转变为“现代高效安全的多范式语言”。
更多推荐

所有评论(0)