【C++进阶】C++11
【C++进阶】C++11
1. C++11简介
C++11是C++语言的重大更新,距离上一个标准C++03已有8年之久。这个标准带来了约140个新特性,修复了约600个缺陷,使得C++变得更现代化、更安全、更高效。
发展历程:
- 1998年:C++98标准发布
- 2003年:C++03标准发布(主要是漏洞修复)
- 2011年:C++11标准正式发布(原计划2007年,故曾称C++0x)
2. 统一的列表初始化
2.1 {}初始化
C++11扩展了大括号初始化的使用范围,使其适用于所有内置类型和用户自定义类型。
struct Point {int _x;int _y;
};int main() {// C++98方式Point p1 = {1, 2};int arr1[] = {1, 2, 3};// C++11方式Point p2{1, 2}; // 不加等号int arr2[]{1, 2, 3}; // 不加等号int x{5}; // 内置类型// new表达式中的使用int* pa = new int[4]{0, 1, 2, 3};return 0;
}
2.2 std::initializer_list
std::initializer_list允许容器使用列表初始化:
#include <vector>
#include <list>
#include <map>
#include <string>int main() {// STL容器的列表初始化std::vector<int> v = {1, 2, 3, 4};std::list<int> lt = {1, 2};std::map<std::string, std::string> dict = {{"sort", "排序"}, {"insert", "插入"}};// 大括号赋值v = {10, 20, 30};return 0;
}
3. 变量类型推导
3.1 auto关键字
auto让编译器自动推导变量类型:
#include <map>
#include <string>int main() {auto i = 10; // intauto p = &i; // int*auto pf = strcpy; // 函数指针std::map<std::string, std::string> dict = {{"sort", "排序"}, {"insert", "插入"}};// 不再需要写冗长的类型auto it = dict.begin(); // std::map<std::string, std::string>::iteratorreturn 0;
}
3.2 decltype类型推导
decltype推导表达式的类型:
#include <iostream>template<class T1, class T2>
void F(T1 t1, T2 t2) {decltype(t1 * t2) ret; // 推导t1*t2的类型std::cout << typeid(ret).name() << std::endl;
}int main() {const int x = 1;double y = 2.2;decltype(x * y) ret; // doubledecltype(&x) p; // const int*std::cout << typeid(ret).name() << std::endl; // doublestd::cout << typeid(p).name() << std::endl; // const int*F(1, 'a'); // 输出intreturn 0;
}
3.3 nullptr空指针
解决NULL的二义性问题:
void func(int) { /* 处理整数 */ }
void func(int*) { /* 处理指针 */ }int main() {func(0); // 调用func(int)func(NULL); // 可能调用func(int),产生歧义func(nullptr); // 明确调用func(int*)return 0;
}
4. 右值引用与移动语义
4.1 左值 vs 右值
左值:可以取地址、有名字的表达式
右值:不能取地址、临时的表达式
int main() {// 左值示例int a = 10;int* p = &a;*p = 20;// 右值示例10; // 字面量a + 5; // 表达式结果func(); // 返回值(非引用返回)// 右值引用int&& rr1 = 10;int&& rr2 = std::move(a);return 0;
}
4.2 移动构造与移动赋值
解决深拷贝性能问题:
class String {
private:char* _str;size_t _size;size_t _capacity;public:// 移动构造函数String(String&& s) noexcept : _str(nullptr), _size(0), _capacity(0) {std::cout << "移动构造" << std::endl;swap(s); // 窃取资源}// 移动赋值运算符String& operator=(String&& s) noexcept {std::cout << "移动赋值" << std::endl;swap(s);return *this;}void swap(String& s) {std::swap(_str, s._str);std::swap(_size, s._size);std::swap(_capacity, s._capacity);}// 其他成员函数...
};
4.3 完美转发
保持参数的左右值属性:
#include <utility>void process(int& x) { std::cout << "左值" << std::endl; }
void process(int&& x) { std::cout << "右值" << std::endl; }template<typename T>
void perfectForward(T&& t) {process(std::forward<T>(t)); // 完美转发
}int main() {int a = 10;perfectForward(a); // 左值perfectForward(std::move(a)); // 右值perfectForward(20); // 右值return 0;
}
5. lambda表达式
5.1 基本语法
[capture-list](parameters) mutable -> return-type { statement
}
5.2 使用示例
#include <algorithm>
#include <vector>
#include <iostream>struct Goods {std::string _name;double _price;int _evaluate;
};int main() {std::vector<Goods> v = {{"苹果", 2.1, 5}, {"香蕉", 3.0, 4}, {"橙子", 2.2, 3}};// 按价格升序排序std::sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) {return g1._price < g2._price;});// 按评价降序排序std::sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) {return g1._evaluate > g2._evaluate;});return 0;
}
5.3 捕获列表详解
int main() {int a = 10, b = 20;// 值捕获auto f1 = [a] { return a; };// 引用捕获auto f2 = [&a] { a = 100; };// 隐式值捕获所有变量auto f3 = [=] { return a + b; };// 隐式引用捕获所有变量auto f4 = [&] { a = 100; b = 200; };// 混合捕获auto f5 = [=, &b] { return a + b; }; // a值捕获,b引用捕获f2(); // 修改a为100std::cout << f1() << std::endl; // 输出10(副本)return 0;
}
6. 智能指针
#include <memory>void smartPointerDemo() {// 独占所有权std::unique_ptr<int> ptr1 = std::make_unique<int>(10);// 共享所有权std::shared_ptr<int> ptr2 = std::make_shared<int>(20);std::shared_ptr<int> ptr3 = ptr2;// 弱引用,不增加引用计数std::weak_ptr<int> weak = ptr2;
}
7. 多线程编程
7.1 基本线程操作
#include <thread>
#include <iostream>void threadFunc(int n) {for (int i = 0; i < n; ++i) {std::cout << "线程执行: " << i << std::endl;}
}int main() {// 创建线程std::thread t(threadFunc, 5);// 等待线程结束t.join();std::cout << "主线程结束" << std::endl;return 0;
}
7.2 线程同步
#include <thread>
#include <mutex>
#include <atomic>std::mutex mtx;
std::atomic<int> atomic_count{0};
int normal_count = 0;void safeIncrement() {for (int i = 0; i < 100000; ++i) {// 使用互斥锁{std::lock_guard<std::mutex> lock(mtx);++normal_count;}// 使用原子操作++atomic_count;}
}int main() {std::thread t1(safeIncrement);std::thread t2(safeIncrement);t1.join();t2.join();std::cout << "普通计数: " << normal_count << std::endl;std::cout << "原子计数: " << atomic_count << std::endl;return 0;
}
7.3 条件变量
#include <thread>
#include <mutex>
#include <condition_variable>std::mutex mtx;
std::condition_variable cv;
bool ready = false;void worker() {std::unique_lock<std::mutex> lock(mtx);cv.wait(lock, []{ return ready; }); // 等待条件满足std::cout << "Worker开始执行" << std::endl;
}int main() {std::thread t(worker);// 模拟准备工作std::this_thread::sleep_for(std::chrono::seconds(1));{std::lock_guard<std::mutex> lock(mtx);ready = true;}cv.notify_one(); // 通知等待的线程t.join();return 0;
}
8. 其他重要特性
8.1 默认和删除函数
class MyClass {
public:MyClass() = default; // 显式要求生成默认构造函数// 禁止拷贝MyClass(const MyClass&) = delete;MyClass& operator=(const MyClass&) = delete;// 允许移动MyClass(MyClass&&) = default;MyClass& operator=(MyClass&&) = default;
};
8.2 可变参数模板
template<typename T>
void printArg(T t) {std::cout << t << " ";
}// 递归展开参数包
template<typename T, typename... Args>
void printArgs(T value, Args... args) {printArg(value);printArgs(args...);
}// 递归终止
template<typename T>
void printArgs(T value) {printArg(value);std::cout << std::endl;
}int main() {printArgs(1, "hello", 3.14, 'A'); // 输出: 1 hello 3.14 Areturn 0;
}
8.3 委托构造函数
class MyClass {
private:int _value;std::string _name;public:// 委托构造函数MyClass(int value) : MyClass(value, "default") {}MyClass(int value, const std::string& name) : _value(value), _name(name) {}
};
9. 总结
C++11带来的重要改进:
- 性能提升:右值引用、移动语义减少不必要的拷贝
- 代码简洁:auto、lambda、列表初始化让代码更清晰
- 类型安全:nullptr、override、final提高代码安全性
- 并发支持:完整的线程库支持现代并发编程
- 模板增强:可变参数模板、别名模板等强大特性
