38、Cpp11新特性介绍
大约 4 分钟C++C++基础编程程序厨
C++11
是C++
语言的一次重大更新,引入了许多新特性,极大地提升了代码的简洁性。
本文会详细介绍C++11
中主要的几个新特性。
auto关键字与类型推导
auto关键字的作用
auto
关键字用于自动推导变量的类型。编译器会根据变量的初始化表达式推断出变量的类型,简化我们的代码。
使用场景
- 简化复杂类型的声明:例如迭代器、函数指针等。
- 提高代码的可读性:减少冗余的类型声明。
代码示例
#include <iostream>
#include <vector>
using namespace std;
int main() {
auto i = 10; // i的类型推导为int
auto d = 3.14; // d的类型推导为double
auto s = "Hello"; // s的类型推导为const char*
vector<int> vec = {1, 2, 3, 4, 5};
for (auto it = vec.begin(); it != vec.end(); ++it) {
cout << *it << " "; // 输出:1 2 3 4 5
}
cout << endl;
return 0;
}
注意事项
auto
不能用于函数参数类型推导。auto
推导的类型是值类型,如果需要引用类型,可以使用auto&
。
nullptr
与智能指针
nullptr
nullptr
是C++11引入的空指针常量,用于替代NULL
。nullptr
的类型是std::nullptr_t
,可以隐式转换为任何指针类型。
#include <iostream>
using namespace std;
void func(int* ptr) {
if (ptr == nullptr) {
cout << "Pointer is null." << endl;
} else {
cout << "Pointer is not null." << endl;
}
}
int main() {
int* p = nullptr;
func(p); // 输出:Pointer is null.
return 0;
}
智能指针
智能指针是C++11
引入的一种管理动态内存的工具,可以自动释放内存,避免内存泄漏。
shared_ptr
shared_ptr
是一种共享所有权的智能指针,通过引用计数管理内存。
#include <iostream>
#include <memory>
using namespace std;
class MyClass {
public:
MyClass() { cout << "MyClass constructed." << endl; }
~MyClass() { cout << "MyClass destroyed." << endl; }
};
int main() {
shared_ptr<MyClass> ptr1 = make_shared<MyClass>();
{
shared_ptr<MyClass> ptr2 = ptr1; // 引用计数增加
cout << "Inside inner scope." << endl;
} // ptr2离开作用域,引用计数减少
cout << "Outside inner scope." << endl;
return 0;
}
unique_ptr
unique_ptr
是一种独占所有权的智能指针,不能复制,但可以移动。
#include <iostream>
#include <memory>
using namespace std;
class MyClass {
public:
MyClass() { cout << "MyClass constructed." << endl; }
~MyClass() { cout << "MyClass destroyed." << endl; }
};
int main() {
unique_ptr<MyClass> ptr1 = make_unique<MyClass>();
// unique_ptr<MyClass> ptr2 = ptr1; // 错误:不能复制
unique_ptr<MyClass> ptr2 = move(ptr1); // 可以移动
return 0;
}
详见:智能指针
Lambda
表达式与闭包
Lambda
表达式
Lambda
表达式是一种匿名函数,可以在需要函数对象的地方直接定义和使用。
语法如下:
[捕获列表](参数列表) -> 返回类型 { 函数体 }
捕获列表
捕获列表用于指定Lambda
表达式可以访问的外部变量:
[]
:不捕获任何变量。[&]
:以引用方式捕获所有变量。[=]
:以值方式捕获所有变量。[&x, y]
:以引用方式捕获x
,以值方式捕获y
。
代码示例
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> vec = {1, 2, 3, 4, 5};
// 使用Lambda表达式作为谓词
auto isEven = [](int x) { return x % 2 == 0; };
auto it = find_if(vec.begin(), vec.end(), isEven);
if (it != vec.end()) {
cout << "First even number: " << *it << endl; // 输出:First even number: 2
}
// 使用Lambda表达式修改外部变量
int sum = 0;
for_each(vec.begin(), vec.end(), [&sum](int x) { sum += x; });
cout << "Sum of vector: " << sum << endl; // 输出:Sum of vector: 15
return 0;
}
闭包
闭包是指Lambda
表达式与其捕获的外部变量组成的整体。闭包可以在函数调用结束后仍然保留捕获的变量状态。
范围for循环与decltype
范围for循环
通过范围for
循环,可以简化遍历容器或数组的代码。
语法
for (元素类型 变量名 : 容器) {
// 循环体
}
代码示例
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> vec = {1, 2, 3, 4, 5};
// 使用范围for循环遍历vector
for (int x : vec) {
cout << x << " "; // 输出:1 2 3 4 5
}
cout << endl;
return 0;
}
decltype关键字
decltype
关键字用于推导表达式的类型。
使用场景
- 推导复杂表达式的类型。
- 它与
auto
结合使用,推导函数返回类型。
代码示例
#include <iostream>
#include <vector>
using namespace std;
int main() {
int x = 10;
decltype(x) y = 20; // y的类型推导为int
vector<int> vec = {1, 2, 3, 4, 5};
decltype(vec.begin()) it = vec.begin(); // it的类型推导为vector<int>::iterator
cout << "y = " << y << endl; // 输出:y = 20
cout << "*it = " << *it << endl; // 输出:*it = 1
return 0;
}
练习
使用
auto
关键字简化以下代码:std::vector<int>::iterator it = vec.begin();
使用
shared_ptr
和unique_ptr
分别实现一个简单的资源管理类。使用Lambda表达式实现一个通用的排序函数,支持对任意类型的容器进行排序。
使用范围
for
循环遍历一个std::map
,并输出键值对。
