1. C++11新特性概述
C++11标准(原称C++0x)是自1998年C++标准发布以来最重要的更新。作为现代C++的开端,它引入了大量革命性特性,从根本上改变了C++的编程范式。这些特性不仅提升了开发效率,还显著增强了代码的安全性和性能表现。
在实际工程中,C++11特性已被广泛应用于:
- 高性能计算领域(如量化交易系统)
- 游戏开发引擎
- 分布式系统
- 嵌入式实时系统
- 机器学习框架等场景
2. 类型推导与自动类型
2.1 auto关键字
auto实现了编译期类型推导,基本用法:
cpp复制auto x = 5; // int
auto y = 3.14; // double
auto ptr = &x; // int*
2.1.1 推导规则
- 忽略右侧表达式的引用和const/volatile限定
- 指针类型会保留cv限定符
cpp复制const int ci = 10;
auto b = ci; // int (忽略const)
auto &c = ci; // const int& (保留const)
2.1.2 使用场景
- 复杂类型简化:
cpp复制std::map<std::string, std::vector<int>>::iterator it = m.begin();
// 简化为
auto it = m.begin();
- 泛型编程:
cpp复制template<typename T>
void process(T container) {
auto it = container.begin();
// ...
}
注意事项:
- auto不能用于函数参数
- 类非静态成员变量不能使用auto
- 定义多个变量时类型必须一致
2.2 decltype类型推导
decltype用于推导表达式类型,保留表达式的引用和cv属性:
cpp复制int i = 0;
decltype(i) j; // int
decltype((i)) k = i; // int&
2.2.1 推导规则
| 表达式类型 | decltype结果 |
|---|---|
| 变量名 | 变量类型 |
| 函数调用 | 返回值类型 |
| 左值表达式 | T& |
| 右值表达式 | T |
2.3 返回类型后置语法
解决函数返回类型依赖参数类型的问题:
cpp复制template<typename T, typename U>
auto add(T t, U u) -> decltype(t + u) {
return t + u;
}
3. 右值引用与移动语义
3.1 值类别分类
- 左值(lvalue):可取地址的持久对象
- 纯右值(prvalue):临时对象或字面量
- 将亡值(xvalue):即将被移动的对象
3.2 右值引用
cpp复制int &&rref = 42; // 合法
int &&rref2 = x; // 非法,x是左值
int &&rref3 = std::move(x); // 合法
3.3 移动语义实现
移动构造函数示例:
cpp复制class String {
public:
// 移动构造函数
String(String&& other) noexcept
: data_(other.data_), size_(other.size_) {
other.data_ = nullptr;
other.size_ = 0;
}
// 移动赋值运算符
String& operator=(String&& other) noexcept {
if (this != &other) {
delete[] data_;
data_ = other.data_;
size_ = other.size_;
other.data_ = nullptr;
other.size_ = 0;
}
return *this;
}
private:
char* data_;
size_t size_;
};
3.4 完美转发
保持参数原始值类别的转发:
cpp复制template<typename T>
void wrapper(T&& arg) {
// 完美转发
func(std::forward<T>(arg));
}
4. 智能指针体系
4.1 shared_ptr共享指针
引用计数智能指针:
cpp复制std::shared_ptr<Widget> p1(new Widget);
auto p2 = p1; // 引用计数+1
4.1.1 自定义删除器
cpp复制std::shared_ptr<FILE> fp(fopen("file.txt", "r"),
[](FILE* f) { fclose(f); });
4.2 weak_ptr弱引用指针
解决循环引用问题:
cpp复制class Observer {
std::weak_ptr<Subject> subject_;
public:
void observe(std::shared_ptr<Subject> s) {
subject_ = s;
}
void notify() {
if (auto s = subject_.lock()) {
s->doSomething();
}
}
};
4.3 unique_ptr独占指针
独占所有权的智能指针:
cpp复制std::unique_ptr<Resource> res(new Resource);
// 所有权转移
auto res2 = std::move(res);
5. 多线程支持
5.1 线程管理
cpp复制void worker(int num) {
std::cout << "Worker: " << num << "\n";
}
std::thread t(worker, 42);
t.join(); // 或 t.detach()
5.2 同步原语
5.2.1 mutex互斥量
cpp复制std::mutex mtx;
void safe_increment() {
std::lock_guard<std::mutex> lock(mtx);
// 临界区
}
5.2.2 condition_variable条件变量
cpp复制std::condition_variable cv;
std::mutex mtx;
bool ready = false;
void consumer() {
std::unique_lock<std::mutex> lk(mtx);
cv.wait(lk, []{return ready;});
// 处理数据
}
5.3 异步操作
5.3.1 future/promise模式
cpp复制std::promise<int> prom;
auto fut = prom.get_future();
std::thread t([](std::promise<int> p){
p.set_value(42);
}, std::move(prom));
int result = fut.get();
t.join();
5.3.2 async异步调用
cpp复制auto fut = std::async(std::launch::async, []{
return long_computation();
});
// 其他工作
auto result = fut.get();
6. 其他重要特性
6.1 列表初始化
统一初始化语法:
cpp复制std::vector<int> v{1, 2, 3};
struct Point { int x, y; };
Point p{10, 20};
6.2 lambda表达式
cpp复制auto sum = [](int a, int b) { return a + b; };
std::sort(v.begin(), v.end(),
[](int a, int b){ return a > b; });
6.2.1 捕获方式
| 捕获形式 | 说明 |
|---|---|
| [] | 不捕获任何变量 |
| [=] | 值捕获所有变量 |
| [&] | 引用捕获所有变量 |
| [x, &y] | 值捕获x,引用捕获y |
| [this] | 捕获当前类的this指针 |
6.3 constexpr常量表达式
编译期计算:
cpp复制constexpr int factorial(int n) {
return n <= 1 ? 1 : n * factorial(n - 1);
}
int arr[factorial(5)]; // 编译期确定数组大小
7. 实际工程经验
7.1 性能优化建议
- 移动语义优先用于大型对象传递
- 智能指针避免循环引用
- 线程池替代频繁创建线程
- 合理使用noexcept声明
7.2 常见陷阱
- auto推导意外忽略引用:
cpp复制std::vector<bool> features();
auto flag = features()[0]; // 实际为临时对象
- 移动后对象状态不确定:
cpp复制std::string s1 = "data";
std::string s2 = std::move(s1);
// s1状态不确定,只能重新赋值
- 多线程数据竞争:
cpp复制// 错误示例
std::shared_ptr<int> ptr;
void thread_func() {
if (!ptr) {
ptr.reset(new int(42)); // 可能多次初始化
}
}
8. 现代C++开发实践
8.1 工具链支持
- GCC 4.8+ / Clang 3.3+ / MSVC 2013+
- CMake最低版本要求:
cmake复制cmake_minimum_required(VERSION 3.1)
set(CMAKE_CXX_STANDARD 11)
8.2 代码规范建议
- 优先使用智能指针管理资源
- 线程安全函数明确标注
- 移动构造函数声明noexcept
- 接口设计考虑完美转发
8.3 典型应用场景
- 高性能网络库(如asio)
- 并行算法实现
- 资源管理封装
- 回调机制实现
在实际项目迁移到C++11时,建议逐步引入新特性,同时配合静态分析工具(如Clang-Tidy)确保代码质量。对于性能关键路径,应当通过基准测试验证优化效果。
