C++11 - 现代 C++ 的开端
C++11:现代 C++ 的开端
C++11 是 C++ 历史上最重要的标准之一,它彻底改变了 C++ 的编程方式,被称为"现代 C++"的起点。
自动类型推导(auto)
auto x = 42; // int
auto y = 3.14; // double
auto z = std::vector<int>{1, 2, 3}; // std::vector<int>
// 范围 for 循环
std::vector<int> vec = {1, 2, 3, 4, 5};
for (auto& elem : vec) {
elem *= 2;
}Lambda 表达式
// 基本语法
auto lambda = [](int x, int y) { return x + y; };
int result = lambda(3, 4); // 7
// 捕获变量
int a = 10;
auto captureByValue = [a](int x) { return x + a; };
auto captureByRef = [&a](int x) { a += x; };
// 捕获所有
auto captureAll = [=](int x) { return x + a; };
auto captureAllRef = [&](int x) { a += x; };智能指针
#include <memory>
// unique_ptr:独占所有权
std::unique_ptr<int> ptr1 = std::make_unique<int>(42);
// std::unique_ptr<int> ptr2 = ptr1; // 编译错误
// shared_ptr:共享所有权
std::shared_ptr<int> ptr3 = std::make_shared<int>(42);
std::shared_ptr<int> ptr4 = ptr3; // 引用计数 +1
// weak_ptr:弱引用,不增加引用计数
std::weak_ptr<int> ptr5 = ptr3;右值引用与移动语义
// 移动构造函数
class MyClass {
public:
MyClass(MyClass&& other) noexcept
: data_(std::move(other.data_)) {
other.data_ = nullptr;
}
// 移动赋值运算符
MyClass& operator=(MyClass&& other) noexcept {
if (this != &other) {
delete data_;
data_ = std::move(other.data_);
other.data_ = nullptr;
}
return *this;
}
private:
int* data_;
};
// std::move
std::string str1 = "Hello";
std::string str2 = std::move(str1); // str1 现在为空std::function 和 std::bind
#include <functional>
int add(int a, int b) { return a + b; }
// std::function:可调用对象的包装器
std::function<int(int, int)> func = add;
int result = func(3, 4); // 7
// std::bind:绑定参数
auto add5 = std::bind(add, std::placeholders::_1, 5);
int result2 = add5(10); // 15
// 绑定成员函数
struct Calculator {
int multiply(int a, int b) { return a * b; }
};
Calculator calc;
auto multiplyBy2 = std::bind(&Calculator::multiply, &calc, std::placeholders::_1, 2);
int result3 = multiplyBy2(5); // 10std::unordered_map 和 std::unordered_set
#include <unordered_map>
#include <unordered_set>
// 哈希表
std::unordered_map<std::string, int> scores;
scores["Alice"] = 90;
scores["Bob"] = 85;
// 查找
if (scores.find("Alice") != scores.end()) {
std::cout << "Alice's score: " << scores["Alice"] << "\n";
}
// unordered_set
std::unordered_set<int> uniqueValues = {1, 2, 2, 3, 3, 3};
// uniqueValues = {1, 2, 3}std::tuple
#include <tuple>
// 创建 tuple
std::tuple<int, double, std::string> t{42, 3.14, "hello"};
// 获取元素
std::get<0>(t); // 42
std::get<1>(t); // 3.14
std::get<2>(t); // "hello"
// 结构化绑定(C++17)
auto [id, value, name] = t;
// 连接 tuple
auto combined = std::tuple_cat(t, std::make_pair(true, 'a'));std::chrono
#include <chrono>
// 时间点
auto now = std::chrono::system_clock::now();
// duration
using namespace std::chrono_literals;
auto duration = 100ms; // 100 毫秒
auto seconds = 2s; // 2 秒
auto minutes = 5min; // 5 分钟
// 睡眠
std::this_thread::sleep_for(500ms);
// 计时
auto start = std::chrono::high_resolution_clock::now();
// ... 执行操作
auto end = std::chrono::high_resolution_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);std::array
#include <array>
// 固定大小数组
std::array<int, 5> arr = {1, 2, 3, 4, 5};
// 访问元素
arr[0] = 10;
arr.at(1) = 20;
// 迭代
for (const auto& elem : arr) {
std::cout << elem << " ";
}
// 大小
std::cout << "Size: " << arr.size() << "\n"; // 5
// 前后元素
std::cout << "Front: " << arr.front() << "\n";
std::cout << "Back: " << arr.back() << "\n";
// 填充
arr.fill(0);std::forward_list
#include <forward_list>
// 单向链表
std::forward_list<int> list = {1, 2, 3, 4, 5};
// 在前面插入
list.push_front(0);
// 在指定位置后插入
auto it = list.begin();
list.insert_after(it, 100);
// 删除元素
list.pop_front();
list.erase_after(it);
// 遍历
for (const auto& elem : list) {
std::cout << elem << " ";
}
// 检查是否为空
if (list.empty()) {
std::cout << "List is empty\n";
}std::random
#include <random>
// 随机数引擎
std::random_device rd; // 硬件随机数生成器
std::mt19937 gen(rd()); // Mersenne Twister 引擎
// 均匀分布
std::uniform_int_distribution<> dis(1, 100);
int randomInt = dis(gen); // 1-100 之间的随机整数
// 浮点数分布
std::uniform_real_distribution<> disReal(0.0, 1.0);
double randomDouble = disReal(gen);
// 正态分布
std::normal_distribution<> normal(5.0, 2.0);
double normalValue = normal(gen);
// 伯努利分布
std::bernoulli_distribution bernoulli(0.5);
bool coinFlip = bernoulli(gen);std::regex
#include <regex>
// 正则表达式匹配
std::string text = "Hello, World! 123";
std::regex pattern(R"(\d+)"); // 匹配数字
std::smatch matches;
if (std::regex_search(text, matches, pattern)) {
std::cout << "Found: " << matches[0] << "\n"; // 123
}
// 正则表达式替换
std::string result = std::regex_replace(text, std::regex(R"(\d+)"), "NUM");
std::cout << result << "\n"; // Hello, World! NUM
// 正则表达式迭代
std::regex word_pattern(R"(\w+)");
std::sregex_iterator it(text.begin(), text.end(), word_pattern);
std::sregex_iterator end;
for (; it != end; ++it) {
std::cout << it->str() << "\n";
}范围 for 循环
std::vector<int> vec = {1, 2, 3, 4, 5};
// 只读
for (const auto& elem : vec) {
std::cout << elem << " ";
}
// 修改
for (auto& elem : vec) {
elem *= 2;
}
// 数组
int arr[] = {1, 2, 3};
for (auto& x : arr) {
x *= 2;
}初始化列表
// 统一初始化
int x{42};
std::vector<int> vec{1, 2, 3, 4, 5};
std::map<std::string, int> m{
{"apple", 1},
{"banana", 2}
};
// 防止窄化转换
// int y{3.14}; // 编译错误nullptr
void func(int* ptr) {}
void func(int x) {}
func(nullptr); // 调用 func(int*)
// func(NULL); // 可能有歧义
int* ptr = nullptr;constexpr
constexpr int factorial(int n) {
return n <= 1 ? 1 : n * factorial(n - 1);
}
constexpr int result = factorial(5); // 编译期计算类型别名
using String = std::string;
using IntVector = std::vector<int>;
// 模板别名
template<typename T>
using Vec = std::vector<T>;
Vec<int> v; // std::vector<int>委托构造函数
class MyClass {
public:
MyClass(int x, int y) : x_(x), y_(y) {}
// 委托给上面的构造函数
MyClass(int x) : MyClass(x, 0) {}
MyClass() : MyClass(0, 0) {}
private:
int x_, y_;
};override 和 final
class Base {
public:
virtual void func() {}
virtual void finalFunc() final {}
};
class Derived : public Base {
public:
void func() override {} // 明确表示重写
// void finalFunc() override {} // 编译错误,final 函数不能重写
};
class FinalClass final : public Base {
// 不能被继承
};enum class
enum class Color { Red, Green, Blue };
enum class Animal { Dog, Cat };
Color c = Color::Red;
// Color c2 = Red; // 编译错误,需要作用域
// if (c == Animal::Dog) {} // 编译错误,不同枚举类型不能比较
// 显式转换
int value = static_cast<int>(Color::Red); // 0静态断言
static_assert(sizeof(int) == 4, "int must be 4 bytes");
template<typename T>
void checkSize() {
static_assert(sizeof(T) >= 4, "Type must be at least 4 bytes");
}变参模板
// 打印任意数量的参数
template<typename... Args>
void print(Args... args) {
((std::cout << args << " "), ...); // 折叠表达式(C++17)
std::cout << "\n";
}
// 递归展开
template<typename T>
T sum(T first) {
return first;
}
template<typename T, typename... Args>
T sum(T first, Args... rest) {
return first + sum(rest...);
}
print(1, 2, 3, "hello"); // 1 2 3 hello
int total = sum(1, 2, 3, 4, 5); // 15常用特性总结
最常用的 C++11 特性:
auto类型推导- Lambda 表达式
- 智能指针(
unique_ptr,shared_ptr) - 范围 for 循环
nullptroverride关键字enum class








