C++11 全新全面特性总结
核心思想:C++11 是 C++ 语言的一次革命性升级,被称为"现代C++的起点"。它引入了移动语义、智能指针、Lambda、类型推导、并发支持等大量新特性,从根本上改变了C++的编程范式,使代码更安全、更简洁、更高效。
🚀 1. 类型推导与初始化
1.1 auto 类型推导:
- 让编译器根据初始化表达式自动推导变量类型
- 减少冗长的类型声明,提高可读性
C++
// ❌ C++98 繁琐写法
std::map<std::string, std::vector<int>>::iterator it = myMap.begin();
// ✅ C++11 auto 简洁写法
auto it = myMap.begin();
// auto 与 const/引用 配合
const auto& ref = someExpression; // const 引用
auto* ptr = &someObject; // 指针
// ⚠️ 注意:auto 不能用于函数参数(C++11),不能用于类成员变量
1.2 decltype 类型推导:
- 在不求值的情况下获取表达式的类型
- 常用于模板编程和返回类型推导
C++
int x = 42;
decltype(x) y = 100; // y 的类型是 int
// 配合 auto 用于尾置返回类型
template <typename T, typename U>
auto add(T a, U b) -> decltype(a + b) {
return a + b;
}
// decltype 保留引用和 const 属性
const int& cr = x;
decltype(cr) z = y; // z 的类型是 const int&
// decltype((x)) 注意双括号
decltype((x)) ref = x; // ref 的类型是 int&(左值表达式)
1.3 统一初始化(花括号初始化):
C++
// 花括号 {} 可以在任何地方进行初始化
int a{5}; // 变量
int arr[]{1, 2, 3}; // 数组
std::vector<int> v{1, 2, 3, 4}; // 容器
std::map<std::string, int> m{{"a", 1}, {"b", 2}}; // map
// 防止窄化转换(narrowing conversion)
// int x{3.14}; // ❌ 编译错误!防止精度丢失
int y = 3.14; // ⚠️ 仅警告,允许编译
// 类的成员初始化
struct Point {
int x{0}; // 类内默认初始化(C++11新增)
int y{0};
};
1.4 std::initializer_list:
C++
#include <initializer_list>
class MyContainer {
std::vector<int> data_;
public:
// 支持初始化列表构造
MyContainer(std::initializer_list<int> init) : data_(init) {}
void append(std::initializer_list<int> values) {
data_.insert(data_.end(), values.begin(), values.end());
}
};
void example() {
MyContainer c = {1, 2, 3, 4, 5};
c.append({6, 7, 8});
// ⚠️ 注意 vector 的构造歧义
std::vector<int> v1(5, 3); // 5个元素,每个值为3:{3,3,3,3,3}
std::vector<int> v2{5, 3}; // 2个元素:{5, 3}
}
📦 2. 移动语义与右值引用
2.1 右值引用 (&&):
- C++11 最核心的特性之一
- 区分"可以安全窃取资源"的临时对象
C++
/*
* 值类别(Value Categories)
* ┌──────────┬──────────────────────────────────────┐
* │ 左值 │ 有名字、可取地址的表达式 │
* │ (lvalue) │ 例:变量名、*ptr、str[0] │
* ├──────────┼──────────────────────────────────────┤
* │ 右值 │ 临时的、无名的、即将销毁的表达式 │
* │ (rvalue) │ 例:42、x+y、std::string("hello") │
* └──────────┴──────────────────────────────────────┘
*/
void process(int& x) { std::cout << "左值引用\n"; }
void process(int&& x) { std::cout << "右值引用\n"; }
void example() {
int a = 10;
process(a); // 左值引用
process(42); // 右值引用
process(a + 1); // 右值引用
}
2.2 移动构造与移动赋值:
C++
class BigBuffer {
int* data_;
size_t size_;
public:
// 构造函数
BigBuffer(size_t n) : data_(new int[n]), size_(n) {
std::cout << "构造: 分配 " << n << " 个int\n";
}
// 拷贝构造(深拷贝,开销大)
BigBuffer(const BigBuffer& other)
: data_(new int[other.size_]), size_(other.size_) {
std::copy(other.data_, other.data_ + size_, data_);
std::cout << "拷贝构造: 复制 " << size_ << " 个int\n";
}
// ✅ 移动构造(窃取资源,开销极小)
BigBuffer(BigBuffer&& other) noexcept
: data_(other.data_), size_(other.size_) {
other.data_ = nullptr; // 让源对象放弃资源
other.size_ = 0;
std::cout << "移动构造: 零拷贝!\n";
}
// ✅ 移动赋值
BigBuffer& operator=(BigBuffer&& other) noexcept {
if (this != &other) {
delete[] data_;
data_ = other.data_;
size_ = other.size_;
other.data_ = nullptr;
other.size_ = 0;
}
std::cout << "移动赋值: 零拷贝!\n";
return *this;
}
~BigBuffer() { delete[] data_; }
};
void example() {
BigBuffer a(1000000);
BigBuffer b = std::move(a); // 移动构造,而非拷贝百万个int
// 此后 a 处于"有效但不确定"的状态,不应再使用其数据
}
2.3 std::move 与 std::forward:
C++
#include <utility>
// std::move:将左值无条件转为右值引用(本身不移动任何东西)
void move_example() {
std::string s = "Hello, World!";
std::string s2 = std::move(s); // s 的内容被"移走"
// s 现在为空(或处于有效但不确定状态)
std::cout << "s2 = " << s2 << "\n"; // "Hello, World!"
}
// std::forward:完美转发,保持参数的值类别
template <typename T>
void wrapper(T&& arg) {
// 如果传入左值 → 转发为左值
// 如果传入右值 → 转发为右值
target(std::forward<T>(arg));
}
// ⚠️ 常见误区
void pitfalls() {
std::string s = "test";
// ❌ move 后继续使用
std::string s2 = std::move(s);
// std::cout << s; // 未定义行为(实践中通常为空,但不应依赖)
// ❌ 对 const 对象 move 无效(会退化为拷贝)
const std::string cs = "const";
std::string s3 = std::move(cs); // 实际调用的是拷贝构造
}
⚡ 3. Lambda 表达式
3.1 基本语法:
C++
/*
* Lambda 语法结构:
* ┌─────────────────────────────────────────────────┐
* │ [捕获列表](参数列表) -> 返回类型 { 函数体 } │
* └─────────────────────────────────────────────────┘
*
* 捕获方式:
* [=] 值捕获所有外部变量
* [&] 引用捕获所有外部变量
* [x] 值捕获 x
* [&x] 引用捕获 x
* [=, &x] 默认值捕获,x 引用捕获
* [&, x] 默认引用捕获,x 值捕获
* [this] 捕获当前对象指针
*/
void lambda_basics() {
int multiplier = 3;
// 最简 lambda
auto greet = []() { std::cout << "Hello!\n"; };
greet();
// 带参数和捕获
auto multiply = [multiplier](int x) { return x * multiplier; };
std::cout << multiply(5) << "\n"; // 15
// 引用捕获(可修改外部变量)
int count = 0;
auto increment = [&count]() { ++count; };
increment();
increment();
std::cout << count << "\n"; // 2
// mutable:允许修改值捕获的副本
int val = 10;
auto modifier = [val]() mutable {
val += 5; // 修改的是内部副本
return val;
};
std::cout << modifier() << "\n"; // 15
std::cout << val << "\n"; // 10(原始值不变)
}
3.2 Lambda 与标准算法结合:
C++
#include <algorithm>
#include <vector>
void lambda_with_algorithms() {
std::vector<int> nums = {1, 5, 3, 8, 2, 9, 4, 7, 6};
// 自定义排序
std::sort(nums.begin(), nums.end(),
[](int a, int b) { return a > b; }); // 降序
// 条件计数
int threshold = 5;
int count = std::count_if(nums.begin(), nums.end(),
[threshold](int n) { return n > threshold; });
// 变换
std::vector<int> squared;
std::transform(nums.begin(), nums.end(), std::back_inserter(squared),
[](int n) { return n * n; });
// 遍历
std::for_each(nums.begin(), nums.end(),
[](int n) { std::cout << n << " "; });
}
🛡️ 4. 智能指针
4.1 三种智能指针:
C++
#include <memory>
/*
* 智能指针对比:
* ┌──────────────┬─────────────────────────────────────┐
* │ unique_ptr │ 独占所有权,不可复制,可移动 │
* │ shared_ptr │ 共享所有权,引用计数 │
* │ weak_ptr │ 弱引用,不增加引用计数,打破循环引用 │
* └──────────────┴─────────────────────────────────────┘
*/
// unique_ptr:独占所有权
void unique_ptr_example() {
// ✅ 推荐使用 make_unique(C++14,C++11需手动new)
std::unique_ptr<int> p1(new int(42));
// auto p1 = std::make_unique<int>(42); // C++14
std::cout << *p1 << "\n"; // 42
// ❌ 不可复制
// std::unique_ptr<int> p2 = p1; // 编译错误
// ✅ 可以移动
std::unique_ptr<int> p2 = std::move(p1);
// p1 现在为 nullptr
// 管理数组
std::unique_ptr<int[]> arr(new int[10]);
arr[0] = 1;
// 自定义删除器
auto fileDeleter = [](FILE* fp) {
if (fp) fclose(fp);
};
std::unique_ptr<FILE, decltype(fileDeleter)>
file(fopen("test.txt", "r"), fileDeleter);
}
// shared_ptr:共享所有权
void shared_ptr_example() {
auto sp1 = std::make_shared<std::string>("Hello");
std::cout << sp1.use_count() << "\n"; // 1
{
auto sp2 = sp1; // 引用计数 +1
std::cout << sp1.use_count() << "\n"; // 2
*sp2 = "World";
}
// sp2 离开作用域,引用计数 -1
std::cout << sp1.use_count() << "\n"; // 1
std::cout << *sp1 << "\n"; // "World"
}
// weak_ptr:打破循环引用
struct Node {
std::shared_ptr<Node> next;
std::weak_ptr<Node> prev; // ✅ 使用 weak_ptr 防止循环引用
~Node() { std::cout << "Node destroyed\n"; }
};
void weak_ptr_example() {
auto n1 = std::make_shared<Node>();
auto n2 = std::make_shared<Node>();
n1->next = n2;
n2->prev = n1; // weak_ptr 不增加引用计数
// 使用 weak_ptr
if (auto locked = n2->prev.lock()) { // 提升为 shared_ptr
std::cout << "prev node is alive\n";
}
}
// n1、n2 离开作用域后都能正常销毁(无循环引用)
🏗️ 5. 类相关新特性
5.1 override 与 final:
C++
class Base {
public:
virtual void draw() const { std::cout << "Base::draw\n"; }
virtual void update() { std::cout << "Base::update\n"; }
virtual ~Base() = default;
};
class Derived : public Base {
public:
// ✅ override 明确标识覆盖,编译器会检查
void draw() const override { std::cout << "Derived::draw\n"; }
// ❌ 如果签名不匹配,编译器报错
// void draw() override { } // 错误!缺少 const,签名不匹配
// ✅ final 禁止进一步覆盖
void update() final { std::cout << "Derived::update\n"; }
};
// ✅ final 也可用于类,禁止继承
class FinalClass final : public Derived {
// void update() override { } // ❌ 错误!update 被标记为 final
};
// class SubFinal : public FinalClass { }; // ❌ 错误!FinalClass 不能被继承
5.2 default 与 delete:
C++
class MyClass {
public:
// ✅ 显式要求编译器生成默认实现
MyClass() = default;
MyClass(const MyClass&) = default;
MyClass& operator=(const MyClass&) = default;
~MyClass() = default;
// ✅ 显式禁止某些操作
MyClass(MyClass&&) = delete; // 禁止移动构造
MyClass& operator=(MyClass&&) = delete; // 禁止移动赋值
};
// 禁止特定类型的隐式转换
class OnlyInt {
public:
void process(int x) { std::cout << x << "\n"; }
void process(double) = delete; // ❌ 禁止 double 参数
void process(bool) = delete; // ❌ 禁止 bool 参数
};
// 不可复制类(单例等场景)
class NonCopyable {
public:
NonCopyable() = default;
NonCopyable(const NonCopyable&) = delete;
NonCopyable& operator=(const NonCopyable&) = delete;
};
5.3 委托构造函数与继承构造函数:
C++
// 委托构造函数
class DatabaseConnection {
std::string host_;
int port_;
std::string dbName_;
public:
// 主构造函数
DatabaseConnection(const std::string& host, int port, const std::string& db)
: host_(host), port_(port), dbName_(db) {
std::cout << "Connecting to " << host_ << ":" << port_ << "\n";
}
// ✅ 委托给主构造函数
DatabaseConnection(const std::string& host)
: DatabaseConnection(host, 3306, "default") {}
DatabaseConnection()
: DatabaseConnection("localhost") {}
};
// 继承构造函数
class Base {
public:
Base(int x) { std::cout << "Base(" << x << ")\n"; }
Base(int x, int y) { std::cout << "Base(" << x << "," << y << ")\n"; }
};
class Derived : public Base {
public:
using Base::Base; // ✅ 继承 Base 的所有构造函数
// 不需要手动逐个转发
};
void example() {
Derived d1(42); // 调用 Base(int)
Derived d2(1, 2); // 调用 Base(int, int)
}
5.4 类内成员初始化:
C++
class Widget {
int width_ = 100; // ✅ 类内直接初始化
int height_ = 200;
std::string name_ = "default";
std::vector<int> data_{1, 2, 3}; // 花括号也可以
public:
Widget() = default; // 使用类内默认值
// 构造函数中的初始化列表会覆盖类内默认值
Widget(int w, int h) : width_(w), height_(h) {}
// name_ 和 data_ 仍使用默认值
};
🧩 6. 模板与泛型增强
6.1 可变参数模板(Variadic Templates):
C++
// 递归展开参数包
// 终止条件
void print() {
std::cout << "\n";
}
// 递归模板
template <typename T, typename... Args>
void print(const T& first, const Args&... rest) {
std::cout << first;
if (sizeof...(rest) > 0) std::cout << ", ";
print(rest...); // 递归展开
}
void example() {
print(1, "hello", 3.14, 'A');
// 输出:1, hello, 3.14, A
}
// 完美转发工厂函数
template <typename T, typename... Args>
std::unique_ptr<T> make_unique_cpp11(Args&&... args) {
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
6.2 模板别名(using):
C++
// ✅ C++11 using 别名(比 typedef 更清晰,支持模板)
using StringVector = std::vector<std::string>;
using IntPair = std::pair<int, int>;
// ✅ 模板别名(typedef 做不到)
template <typename T>
using Vec = std::vector<T, MyAllocator<T>>;
Vec<int> myVec; // 等价于 std::vector<int, MyAllocator<int>>
// 函数指针别名
using Callback = void(*)(int, int);
// 等价于:typedef void (*Callback)(int, int);
// std::function 别名
using Handler = std::function<void(const std::string&)>;
6.3 static_assert(编译期断言):
C++
// 编译期检查条件,不满足则报错
template <typename T>
class NumericContainer {
static_assert(std::is_arithmetic<T>::value,
"T must be an arithmetic type!");
std::vector<T> data_;
};
NumericContainer<int> ok; // ✅ 编译通过
// NumericContainer<std::string> bad; // ❌ 编译错误:T must be an arithmetic type!
// 检查平台特性
static_assert(sizeof(int) >= 4, "int must be at least 32 bits");
static_assert(sizeof(void*) == 8, "This code requires 64-bit platform");
6.4 外部模板(Extern Templates):
C++
// ---- header.h ----
template <typename T>
void heavyFunction(T val) { /* 复杂实现 */ }
// ---- a.cpp ----
// 在此编译单元实例化
template void heavyFunction<int>(int);
// ---- b.cpp ----
// ✅ 告诉编译器:不要在这里实例化,链接时从别处获取
extern template void heavyFunction<int>(int);
// 减少重复实例化,加快编译速度
🔧 7. 语法增强与语法糖
7.1 nullptr:
C++
// ❌ C++98:NULL 是整数 0,可能导致歧义
void process(int x) { std::cout << "int\n"; }
void process(char* p) { std::cout << "pointer\n"; }
// process(NULL); // 歧义!NULL 是 0,可能调用 int 版本
// ✅ C++11:nullptr 是专门的空指针类型
process(nullptr); // 明确调用 pointer 版本
// nullptr 的类型是 std::nullptr_t
std::nullptr_t np = nullptr;
7.2 范围 for 循环:
C++
void range_for_examples() {
std::vector<int> nums = {1, 2, 3, 4, 5};
// 只读遍历
for (const auto& n : nums) {
std::cout << n << " ";
}
// 修改元素
for (auto& n : nums) {
n *= 2;
}
// 遍历 initializer_list
for (auto x : {10, 20, 30}) {
std::cout << x << " ";
}
// 遍历 map
std::map<std::string, int> scores = {{"Alice", 90}, {"Bob", 85}};
for (const auto& [name, score] : scores) { // C++17 结构化绑定
std::cout << name << ": " << score << "\n";
}
// C++11 写法
for (const auto& pair : scores) {
std::cout << pair.first << ": " << pair.second << "\n";
}
}
7.3 强类型枚举(enum class):
C++
// ❌ C++98 枚举:名称泄漏到外层作用域,可隐式转为 int
enum Color { RED, GREEN, BLUE };
// int x = RED; // 可以隐式转换
// ✅ C++11 enum class:强类型,有作用域
enum class Color : uint8_t { // 可指定底层类型
Red,
Green,
Blue
};
enum class Direction {
Up, Down, Left, Right
};
void example() {
Color c = Color::Red; // 必须使用作用域
// int x = c; // ❌ 编译错误,不能隐式转换
int x = static_cast<int>(c); // ✅ 必须显式转换
// 不同 enum class 的成员名不冲突
// Color::Up // ❌ 错误,Up 不在 Color 中
}
7.4 constexpr(编译期常量表达式):
C++
// 编译期计算
constexpr int factorial(int n) {
return (n <= 1) ? 1 : n * factorial(n - 1);
}
constexpr int val = factorial(5); // 编译期计算为 120
// constexpr 变量
constexpr double PI = 3.14159265358979;
constexpr int MAX_SIZE = 1024;
// ⚠️ C++11 中 constexpr 函数限制较多(只能有一个 return 语句)
// C++14 放宽了限制
7.5 noexcept:
C++
// 声明函数不会抛出异常
void safe_function() noexcept {
// 如果抛出异常,程序直接调用 std::terminate
}
// 条件 noexcept
template <typename T>
void swap_wrapper(T& a, T& b) noexcept(noexcept(std::swap(a, b))) {
std::swap(a, b);
}
// 移动操作应标记 noexcept(容器优化依赖于此)
class MyClass {
public:
MyClass(MyClass&& other) noexcept { /* ... */ }
// vector 在 resize 时,如果移动构造是 noexcept,
// 会使用移动而非拷贝
};
7.6 原始字符串字面量与用户自定义字面量:
C++
// 原始字符串(无需转义)
std::string path = R"(C:\Users\test\file.txt)"; // 无需 \\
std::string json = R"({"name": "Alice", "age": 30})";
std::string regex_pat = R"(\d+\.\d+)"; // 正则更清晰
// 自定义分隔符
std::string complex_str = R"delimiter(He said "hello")delimiter";
// 用户自定义字面量
constexpr long double operator""_deg(long double deg) {
return deg * 3.14159265358979 / 180.0;
}
constexpr unsigned long long operator""_KB(unsigned long long kb) {
return kb * 1024;
}
void example() {
auto angle = 90.0_deg; // 弧度值
auto size = 64_KB; // 65536
}
🧵 8. 并发与多线程支持
8.1 std::thread:
C++
#include <thread>
#include <mutex>
#include <iostream>
void worker(int id) {
std::cout << "Thread " << id << " running\n";
}
void thread_example() {
std::thread t1(worker, 1);
std::thread t2(worker, 2);
// Lambda 作为线程函数
std::thread t3([]() {
std::cout << "Lambda thread\n";
});
t1.join(); // 等待线程结束
t2.join();
t3.join();
// detach() 可以将线程与对象分离,让线程在后台运行
}
8.2 互斥量与锁:
C++
#include <mutex>
class ThreadSafeCounter {
int count_ = 0;
mutable std::mutex mtx_;
public:
void increment() {
std::lock_guard<std::mutex> lock(mtx_); // RAII 自动加锁/解锁
++count_;
}
int get() const {
std::lock_guard<std::mutex> lock(mtx_);
return count_;
}
};
// 避免死锁:同时锁定多个互斥量
std::mutex m1, m2;
void safe_lock() {
std::lock(m1, m2); // 同时锁定,避免死锁
std::lock_guard<std::mutex> lg1(m1, std::adopt_lock);
std::lock_guard<std::mutex> lg2(m2, std::adopt_lock);
// 操作共享数据...
}
8.3 std::future 与 std::async:
C++
#include <future>
int compute(int x) {
std::this_thread::sleep_for(std::chrono::seconds(1));
return x * x;
}
void async_example() {
// 异步执行,返回 future
std::future<int> result = std::async(std::launch::async, compute, 42);
std::cout << "Doing other work...\n";
// 获取结果(阻塞直到完成)
int value = result.get();
std::cout << "Result: " << value << "\n"; // 1764
// promise 手动设置结果
std::promise<std::string> prom;
std::future<std::string> fut = prom.get_future();
std::thread t([&prom]() {
prom.set_value("Hello from thread!");
});
std::cout << fut.get() << "\n";
t.join();
}
8.4 原子操作:
C++
#include <atomic>
std::atomic<int> counter{0}; // 无需互斥量的线程安全计数器
void atomic_increment() {
for (int i = 0; i < 10000; ++i) {
counter.fetch_add(1, std::memory_order_relaxed);
// 或者简单写为:
// ++counter;
}
}
void atomic_example() {
std::thread t1(atomic_increment);
std::thread t2(atomic_increment);
t1.join();
t2.join();
std::cout << "Counter: " << counter.load() << "\n"; // 20000(精确)
}
📚 9. 新增标准库组件
9.1 std::array、std::tuple、std::pair增强:
C++
#include <array>
#include <tuple>
void new_containers() {
// std::array:固定大小数组,替代C风格数组
std::array<int, 5> arr = {1, 2, 3, 4, 5};
arr.at(2); // 带边界检查
arr.size(); // 编译期已知
arr.fill(0); // 全部填零
// std::tuple:异构元素组
auto t = std::make_tuple(42, "hello", 3.14);
int x = std::get<0>(t); // 42
const char* s = std::get<1>(t); // "hello"
// tie 解包
int a; std::string b; double c;
std::tie(a, b, c) = std::make_tuple(1, "world", 2.71);
// 忽略某些值
std::tie(a, std::ignore, c) = std::make_tuple(10, "skip", 99.9);
}
9.2 无序容器(哈希表):
C++
#include <unordered_map>
#include <unordered_set>
void unordered_example() {
// 平均 O(1) 的查找/插入/删除
std::unordered_map<std::string, int> umap;
umap["Alice"] = 90;
umap["Bob"] = 85;
// 查找
auto it = umap.find("Alice");
if (it != umap.end()) {
std::cout << it->second << "\n"; // 90
}
std::unordered_set<int> uset = {1, 2, 3, 4, 5};
std::cout << uset.count(3) << "\n"; // 1
/*
* 有序 vs 无序 对比:
* ┌────────────────┬──────────┬─────────────┐
* │ │ map │ unordered_map│
* ├────────────────┼──────────┼─────────────┤
* │ 底层结构 │ 红黑树 │ 哈希表 │
* │ 查找复杂度 │ O(log n) │ 平均 O(1) │
* │ 是否有序 │ ✅ │ ❌ │
* │ 内存开销 │ 较小 │ 较大 │
* └────────────────┴──────────┴─────────────┘
*/
}
9.3 std::function 与 std::bind:
C++
#include <functional>
void free_function(int x) { std::cout << "free: " << x << "\n"; }
struct Functor {
void operator()(int x) const { std::cout << "functor: " << x << "\n"; }
void method(int x) const { std::cout << "method: " << x << "\n"; }
};
void function_example() {
// std::function:通用可调用对象包装器
std::function<void(int)> fn;
fn = free_function; // 自由函数
fn(1);
fn = Functor(); // 函数对象
fn(2);
fn = [](int x) { std::cout << "lambda: " << x << "\n"; }; // Lambda
fn(3);
// std::bind:绑定参数
Functor obj;
auto bound = std::bind(&Functor::method, &obj, std::placeholders::_1);
bound(42); // 调用 obj.method(42)
// 绑定部分参数
auto add = [](int a, int b) { return a + b; };
auto add5 = std::bind(add, 5, std::placeholders::_1);
std::cout << add5(3) << "\n"; // 8
}
9.4 chrono 时间库:
C++
#include <chrono>
#include <thread>
void chrono_example() {
// 高精度计时
auto start = std::chrono::high_resolution_clock::now();
// 模拟耗时操作
std::this_thread::sleep_for(std::chrono::milliseconds(150));
auto end = std::chrono::high_resolution_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
std::cout << "Elapsed: " << elapsed.count() << " μs\n";
// 时间点运算
auto now = std::chrono::system_clock::now();
auto tomorrow = now + std::chrono::hours(24);
}
9.5 regex 正则表达式:
C++
#include <regex>
#include <string>
void regex_example() {
std::string text = "Email: alice@example.com, bob@test.org";
std::regex email_pattern(R"((\w+)@(\w+\.\w+))");
// 搜索所有匹配
auto begin = std::sregex_iterator(text.begin(), text.end(), email_pattern);
auto end = std::sregex_iterator();
for (auto it = begin; it != end; ++it) {
std::smatch match = *it;
std::cout << "Full: " << match[0]
<< ", User: " << match[1]
<< ", Domain: " << match[2] << "\n";
}
// 替换
std::string result = std::regex_replace(text, email_pattern, "[REDACTED]");
}
9.6 random 随机数:
C++
#include <random>
void random_example() {
// ✅ 现代随机数生成(替代 rand()/srand())
std::random_device rd; // 硬件熵源(种子)
std::mt19937 gen(rd()); // Mersenne Twister 引擎
std::uniform_int_distribution<> dice(1, 6); // 均匀整数分布
std::normal_distribution<> normal(0.0, 1.0); // 正态分布
std::bernoulli_distribution coin(0.5); // 伯努利分布
for (int i = 0; i < 5; ++i) {
std::cout << "Dice: " << dice(gen)
<< ", Normal: " << normal(gen)
<< ", Coin: " << coin(gen) << "\n";
}
}
📊 10. 综合特性速查表 📊
c++
┌──────────────────────┬───────────────────────────────────────────────┐
│ 特性分类 │ 具体特性 │
├──────────────────────┼───────────────────────────────────────────────┤
│ 类型与推导 │ auto, decltype, 尾置返回类型 │
├──────────────────────┼───────────────────────────────────────────────┤
│ 初始化 │ 统一初始化{}, initializer_list, 类内成员初始化 │
├──────────────────────┼───────────────────────────────────────────────┤
│ 移动语义 │ 右值引用&&, std::move, std::forward, 移动构造 │
├──────────────────────┼───────────────────────────────────────────────┤
│ Lambda │ 捕获列表, mutable, 与算法配合 │
├──────────────────────┼───────────────────────────────────────────────┤
│ 智能指针 │ unique_ptr, shared_ptr, weak_ptr │
├──────────────────────┼───────────────────────────────────────────────┤
│ 类增强 │ override, final, default, delete, │
│ │ 委托构造, 继承构造 │
├──────────────────────┼───────────────────────────────────────────────┤
│ 模板增强 │ 可变参数模板, using别名, static_assert, │
│ │ extern template │
├──────────────────────┼───────────────────────────────────────────────┤
│ 语法改进 │ nullptr, 范围for, enum class, constexpr, │
│ │ noexcept, 原始字符串, 用户自定义字面量 │
├──────────────────────┼───────────────────────────────────────────────┤
│ 并发 │ thread, mutex, lock_guard, atomic, │
│ │ future, async, promise, condition_variable │
├──────────────────────┼───────────────────────────────────────────────┤
│ 新库组件 │ array, tuple, unordered_map/set, │
│ │ function, bind, chrono, regex, random │
└──────────────────────┴───────────────────────────────────────────────┘
💡 关键实践原则
- 优先使用移动语义减少不必要的拷贝
- 实现移动构造/赋值并标记
noexcept - 函数返回局部对象时编译器自动应用 RVO/NRVO
- 实现移动构造/赋值并标记
- 用智能指针替代裸指针管理动态资源
- 默认用
unique_ptr,需要共享时用shared_ptr - 用
weak_ptr打破循环引用
- 默认用
- 用 Lambda 替代简单的函数对象
- 算法配合 Lambda 代替手写循环
- 注意捕获方式(值 vs 引用)对生命周期的影响
- 用
auto简化代码但不滥用- 迭代器类型、复杂模板表达式适合用
auto - 基本类型和需要明确语义的场景保留显式类型
- 迭代器类型、复杂模板表达式适合用
- 用
override/final/delete让意图显式化- 编译器帮你检查错误,防止无声的 bug
- 用标准并发组件替代平台特定 API
std::thread+std::mutex+std::atomic实现可移植并发
总结:
C++11 是现代 C++ 的分水岭,从语言核心到标准库都发生了深刻变革。移动语义 解决了不必要拷贝的性能瓶颈,智能指针 消除了内存泄漏的风险,Lambda 表达式 让函数式编程成为可能,auto/decltype 减少了类型书写的负担,并发库提供了跨平台的多线程支持。
掌握 C++11 新特性不仅是技术升级,更是编程思维的转变:从手动管理资源到 RAII 自动管理,从面向过程循环到算法+Lambda 组合,从平台依赖到标准化可移植。这些特性共同构成了高效、安全、优雅的现代 C++ 编程范式的基础。