C++ 11新特性

C++11引入了众多新特性,以下是一些比较常用且重要的新特性介绍:

1. 语言核心特性增强

  • 自动类型推断(auto关键字)
    编译器可以根据变量的初始值自动推断其类型,简化了复杂类型变量的声明,尤其适用于迭代器、lambda表达式等返回复杂类型的情况。例如:
auto i = 5;  // i被推断为int类型
auto it = std::vector<int>{1, 2, 3}.begin();  // it被推断为std::vector<int>::iterator类型
  • 范围for循环
    能够简洁地遍历容器或可迭代对象,让代码更易读、易写。语法形式如下:
std::vector<int> vec = {1, 2, 3};
for (auto element : vec) {
    std::cout << element << " ";
}
// 输出: 1 2 3
  • nullptr关键字
    用于表示空指针,替代原来容易产生歧义的NULL(在C++中NULL实际是int类型的宏定义,而nullptr是专门的指针类型常量),增强了代码的类型安全性。例如:
int* ptr = nullptr;

2. 初始化列表(std::initializer_list

允许使用花括号{}来初始化对象,支持对自定义类型、容器等进行初始化,方便且直观。例如:

std::vector<int> v = {1, 2, 3};
struct Point {
    int x;
    int y;
};
Point p = {10, 20};

同时,函数也可以接受初始化列表作为参数,比如:

void printElements(std::initializer_list<int> list) {
    for (auto element : list) {
        std::cout << element << " ";
    }
    std::cout << std::endl;
}
printElements({1, 2, 3});

3. Lambda表达式

可以在代码中创建匿名函数,方便在需要函数对象的地方(如std::sort算法的比较函数、std::for_each的操作函数等)快速定义简单的函数逻辑。语法形式一般为:

[捕获列表](参数列表) -> 返回类型 {函数体}

例如,对一个vector进行排序,使用lambda表达式定义比较函数:

std::vector<int> numbers = {5, 3, 1, 4, 2};
std::sort(numbers.begin(), numbers.end(), [](int a, int b) -> bool { return a < b; });

捕获列表可以捕获外部变量供lambda函数内部使用,如按值捕获、按引用捕获等,示例如下:

int factor = 2;
std::vector<int> nums = {1, 2, 3};
std::for_each(nums.begin(), nums.end(), [factor](int& num) { num *= factor; });

4. 右值引用与移动语义

  • 右值引用(&&
    是一种新的引用类型,用于绑定到右值(临时对象、表达式返回值等),与传统左值引用区分开,开启了移动语义等优化操作的可能性。例如:
int&& rvalueRef = 10;  // 绑定到右值(字面量常量)
  • 移动语义
    通过定义移动构造函数(如ClassName(ClassName&& other))和移动赋值运算符(如ClassName& operator=(ClassName&& other)),实现将临时对象(右值)的资源高效地“移动”给另一个对象,避免了传统拷贝语义下的资源深拷贝,提升性能。例如:
class MyString {
private:
    char* data;
    size_t length;
public:
    // 移动构造函数示例
    MyString(MyString&& other) : data(other.data), length(other.length) {
        other.data = nullptr;
        other.length = 0;
    }
    // 省略其他成员函数
};

5. 新的容器和容器相关特性

  • std::array
    是一个固定大小的数组容器,它结合了普通数组的性能优势和容器类的一些方便特性(如beginend迭代器方法等),在编译期确定大小,更安全、易用。例如:
std::array<int, 5> arr = {1, 2, 3, 4, 5};
  • std::forward_list
    是一个单向链表容器,适合一些只需单向遍历、对插入删除操作效率有要求的场景,相比于std::list(双向链表)在空间上可能更节省,操作开销也有不同特点。例如:
std::forward_list<int> flist;
flist.push_front(1);
flist.push_front(2);
  • std::unordered_mapstd::unordered_set
    基于哈希表实现,相比于传统的std::map(红黑树实现)和std::set,在查找、插入、删除操作上平均时间复杂度更低(接近常数时间),适用于对查找性能要求较高、不要求元素有序的场景。例如:
std::unordered_map<std::string, int> umap;
umap["apple"] = 5;
umap["banana"] = 3;

6. 多线程支持(std::threadstd::mutex等)

  • std::thread
    用于创建和管理线程,使得在C++中编写多线程程序更加方便、直观。例如:
#include <iostream>
#include <thread>

void hello() {
    std::cout << "Hello from thread " << std::this_thread::get_id() << std::endl;
}

int main() {
    std::thread t(hello);
    std::cout << "Hello from main thread " << std::this_thread::get_id() << std::endl;
    t.join();
    return 0;
}
  • std::mutex(互斥锁)及其相关类型(std::lock_guard等)
    用于保护共享资源,防止多个线程同时访问导致数据不一致等问题。std::lock_guard是一种方便的RAII(Resource Acquisition Is Initialization)机制的锁管理类,能自动在构造函数中锁定互斥锁,在析构函数中解锁,避免了手动管理锁的释放问题。例如:
std::mutex mutex;
int sharedData = 0;
void increment() {
    std::lock_guard<std::mutex> guard(mutex);
    sharedData++;
}

7. 类型别名(using关键字)

使用using关键字可以为已有类型定义别名,相比typedef,它的语法更加直观、灵活,特别是在定义模板别名等复杂情况时优势明显。例如:

using IntVector = std::vector<int>;
IntVector v = {1, 2, 3};
// 定义函数指针类型别名示例
using FuncPtr = void (*)(int);

8. 委托构造函数(Delegating Constructors)

允许在一个构造函数中调用同一个类的其他构造函数,减少代码重复,方便初始化逻辑的复用。例如:

class Point {
public:
    Point(int xVal, int yVal) : x(xVal), y(yVal) {}
    Point() : Point(0, 0) {}  // 委托构造函数,调用有参数的构造函数进行初始化
private:
    int x;
    int y;
};

9. 显式虚函数重载(override关键字)

在派生类中重写基类的虚函数时,可以使用override关键字来显式表明这是一个重写操作。这样编译器能帮我们检查是否正确重写了虚函数(比如函数签名是否一致等),避免一些因重写错误导致的运行时问题。例如:

class Base {
public:
    virtual void func() {}
};
class Derived : public Base {
public:
    void func() override {  // 使用override关键字
        // 具体实现
    }
};

10. 常量表达式(constexpr

可以让函数或对象在编译期求值,扩大了编译期计算的范围,常用于定义编译期就能确定值的常量、数组大小等,提升程序性能和可预测性。例如:

constexpr int factorial(int n) {
    return (n <= 1)? 1 : n * factorial(n - 1);
}
constexpr int result = factorial(5);  // 在编译期计算阶乘结果

这些只是C++11众多新特性中的一部分,它们为C++编程带来了更多便利、高效以及功能上的拓展,让开发者可以写出更现代、更强大的C++代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值