第15课: 现代C++特性
auto关键字(C++11)
#include <iostream>
#include <vector>
#include <map>
using namespace std;
int main() {
// 自动类型推导
auto x = 10; // int
auto y = 3.14; // double
auto str = "Hello"; // const char*
// 简化复杂类型
vector<int> vec = {1, 2, 3};
auto it = vec.begin(); // vector<int>::iterator
map<string, int> m;
for (auto pair : m) { // 简化遍历
cout << pair.first << ": " << pair.second << endl;
}
return 0;
}
智能指针(C++11)
#include <iostream>
#include <memory>
using namespace std;
class Person {
public:
string name;
Person(string n) : name(n) {
cout << "创建Person: " << name << endl;
}
~Person() {
cout << "销毁Person: " << name << endl;
}
};
int main() {
// unique_ptr:独占所有权
unique_ptr<Person> p1(new Person("张三"));
// unique_ptr<Person> p2 = p1; // 错误!不能拷贝
unique_ptr<Person> p2 = move(p1); // 可以移动
// shared_ptr:共享所有权
shared_ptr<Person> p3 = make_shared<Person>("李四");
shared_ptr<Person> p4 = p3; // 引用计数+1
cout << "引用计数:" << p3.use_count() << endl;
// weak_ptr:弱引用,不增加引用计数
weak_ptr<Person> wp = p3;
cout << "引用计数:" << p3.use_count() << endl;
return 0;
} // 自动释放内存
Lambda表达式(C++11)
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
// 基本lambda
auto add = [](int a, int b) { return a + b; };
cout << "5 + 3 = " << add(5, 3) << endl;
// 捕获外部变量
int x = 10;
auto print = [x]() { cout << "x = " << x << endl; };
print();
// 按引用捕获
int y = 20;
auto modify = [&y]() { y = 30; };
modify();
cout << "y = " << y << endl;
// 在算法中使用
vector<int> vec = {1, 2, 3, 4, 5};
int count = count_if(vec.begin(), vec.end(), [](int x) { return x > 3; });
cout << "大于3的元素:" << count << endl;
// 排序
sort(vec.begin(), vec.end(), [](int a, int b) { return a > b; });
return 0;
}
范围for循环(C++11)
#include <iostream>
#include <vector>
#include <map>
using namespace std;
int main() {
vector<int> vec = {1, 2, 3, 4, 5};
// 只读遍历
for (int num : vec) {
cout << num << " ";
}
cout << endl;
// 修改元素(引用)
for (int &num : vec) {
num *= 2;
}
// 常量引用(避免拷贝)
for (const auto &num : vec) {
cout << num << " ";
}
cout << endl;
// 遍历map
map<string, int> m = {{"a", 1}, {"b", 2}};
for (const auto &[key, value] : m) { // C++17结构化绑定
cout << key << ": " << value << endl;
}
return 0;
}
nullptr(C++11)
#include <iostream>
using namespace std;
void func(int x) {
cout << "调用int版本" << endl;
}
void func(int *ptr) {
cout << "调用指针版本" << endl;
}
int main() {
// func(NULL); // 歧义!NULL是0
func(nullptr); // 明确调用指针版本
int *ptr = nullptr;
if (ptr == nullptr) {
cout << "ptr是空指针" << endl;
}
return 0;
}
右值引用与移动语义(C++11)
#include <iostream>
#include <vector>
using namespace std;
class Array {
private:
int *data;
int size;
public:
Array(int s) : size(s) {
data = new int[size];
cout << "构造函数" << endl;
}
~Array() {
delete[] data;
cout << "析构函数" << endl;
}
// 拷贝构造函数
Array(const Array &other) : size(other.size) {
data = new int[size];
copy(other.data, other.data + size, data);
cout << "拷贝构造函数" << endl;
}
// 移动构造函数
Array(Array &&other) noexcept : data(other.data), size(other.size) {
other.data = nullptr;
other.size = 0;
cout << "移动构造函数" << endl;
}
};
Array createArray() {
return Array(10);
}
int main() {
Array arr1 = createArray(); // 调用移动构造函数
return 0;
}
constexpr(C++11)
#include <iostream>
using namespace std;
// 编译期常量表达式
constexpr int factorial(int n) {
return (n <= 1) ? 1 : n * factorial(n - 1);
}
constexpr int square(int x) {
return x * x;
}
int main() {
// 编译期计算
constexpr int result = factorial(5);
cout << "5! = " << result << endl;
constexpr int arr[square(3)]; // 数组大小必须是编译期常量
cout << "数组大小:" << sizeof(arr) / sizeof(int) << endl;
return 0;
}
结构化绑定(C++17)
#include <iostream>
#include <tuple>
#include <map>
using namespace std;
tuple<int, double, string> getData() {
return {100, 3.14, "Hello"};
}
int main() {
// 解包tuple
auto [num, pi, str] = getData();
cout << num << ", " << pi << ", " << str << endl;
// 遍历map
map<string, int> m = {{"a", 1}, {"b", 2}};
for (const auto &[key, value] : m) {
cout << key << ": " << value << endl;
}
// 数组
int arr[] = {1, 2, 3};
auto [x, y, z] = arr;
cout << x << ", " << y << ", " << z << endl;
return 0;
}
std::optional(C++17)
#include <iostream>
#include <optional>
using namespace std;
optional<int> divide(int a, int b) {
if (b == 0) {
return nullopt; // 返回空值
}
return a / b;
}
int main() {
auto result = divide(10, 2);
if (result.has_value()) {
cout << "结果:" << result.value() << endl;
}
auto result2 = divide(10, 0);
if (!result2) {
cout << "除数为0" << endl;
}
// 提供默认值
cout << "结果:" << result2.value_or(-1) << endl;
return 0;
}
练习题
- 使用智能指针实现一个简单的资源管理类
- 使用lambda表达式实现自定义排序
- 实现一个支持移动语义的字符串类
- 使用constexpr实现编译期计算的数学函数
- 综合运用现代C++特性实现一个小项目