C++学习笔记——C++ 新标准(C++11、C++14、C++17)引入的重要特性

目录

1、简介

2.自动类型推导和初始化

示例代码

3.智能指针

示例代码

[4.Lambda 表达式](#4.Lambda 表达式)

示例代码

5.右值引用和移动语义

示例代码

6.并发编程支持

示例代码

7.其他特性

八、案例:实现一个简单的并发下载器


上一篇文章:

C++标准模板库(STL)是C++的一个重要组成部分,它提供了一套丰富的通用数据结构和算法。STL以其高度模块化、可复用的特性,在C++编程中发挥着重要作用。本篇博客将带你深入了解STL,并介绍其常见的组件和使用方法。

C++学习笔记------标准模板库-CSDN博客C++标准模板库(STL)是C++的一个重要组成部分,它提供了一套丰富的通用数据结构和算法。STL以其高度模块化、可复用的特性,在C++编程中发挥着重要作用。本篇博客将带你深入了解STL,并介绍其常见的组件和使用方法。C++标准模板库(STL)是C++语言的一个标准库,它提供了一套通用的数据结构和算法,以支持高效的编程。STL的设计目标是使程序员能够以简洁、高效和可复用的方式开发代码。// 输出vector的大小return 0;https://blog.csdn.net/m0_62338174/article/details/135573281?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22135573281%22%2C%22source%22%3A%22m0_62338174%22%7D

1、简介

C++ 是一种功能强大的编程语言,它一直在不断发展和演进。自从 C++11 标准发布以来,C++ 引入了许多重要的新特性,如智能指针、Lambda 表达式、右值引用等。随后的 C++14 和 C++17 标准也带来了更多的改进和增强。本篇博客将详细介绍 C++ 新标准引入的一些重要特性,并给出代码示例和详细解释,帮助读者了解和应用这些特性。

2.自动类型推导和初始化

C++11 引入了 auto 关键字和统一的初始化语法,使得变量的类型推导更加方便。在 C++11 之前,我们必须手动指定变量的类型,例如 int、double 等。但是在某些情况下,类型可能比较复杂或者难以确定,使用 auto 关键字可以自动推导出变量的类型。同时,C++11 还引入了统一的初始化语法,允许我们使用初始化列表对变量进行初始化,这样代码更加简洁和易读。

示例代码

复制代码
auto x = 10; // x 的类型被推导为 int
auto y = 3.14; // y 的类型被推导为 double

std::vector<int> nums = {1, 2, 3}; // 使用初始化列表进行初始化

3.智能指针

C++11 引入了智能指针,用于管理动态分配的内存,避免内存泄漏和悬空指针的问题。其中最常用的是 shared_ptr 和 unique_ptr。shared_ptr 允许多个指针共享同一个对象,并且会自动进行内存回收,直到所有指针都不再需要该对象。unique_ptr 则保证每个对象只有一个指针拥有它,可以通过 std::move 函数实现所有权的转移。

示例代码

复制代码
std::shared_ptr<int> p1 = std::make_shared<int>(10); // 使用 make_shared 创建 shared_ptr
std::unique_ptr<int> p2(new int(20)); // 使用 new 创建 unique_ptr

if (p1) {
    std::cout << *p1 << std::endl; // 访问指针指向的值
}

4.Lambda 表达式

C++11 引入了 Lambda 表达式,允许我们在代码中定义匿名函数,简化了函数对象的使用和编写。Lambda 表达式的基本形式为 [ capture-list ] ( params ) mutable exception -> return-type { body },其中 capture-list 表示变量捕获列表,params 表示参数列表,mutable 和 exception 表示是否可变和异常规范,return-type 表示返回类型,body 表示函数体。

示例代码

复制代码
std::vector<int> nums = {1, 2, 3, 4, 5};

// 使用 Lambda 表达式对容器进行遍历和操作
std::for_each(nums.begin(), nums.end(), [](int n) {
    std::cout << n * 2 << " ";
});

5.右值引用和移动语义

C++11 引入了右值引用和移动语义,通过 std::move 函数实现对资源的高效转移,提高了性能和效率。右值引用用 && 表示,可以绑定到临时对象、表达式、返回右值引用的函数等,允许我们对这些对象进行高效的转移和管理。移动语义则是指通过右值引用实现资源的转移,避免了复制和销毁的开销。

示例代码

复制代码
std::string str = "Hello";
std::vector<std::string> vec;

vec.push_back(std::move(str)); // 使用 std::move 转移资源

std::cout << str << std::endl; // 输出为空,str 的资源已被转移

6.并发编程支持

C++11 引入了一套完整的并发编程库,包括原子操作、线程、互斥量、条件变量等,方便开发者进行多线程编程和并发控制。其中最常用的就是 std::thread 类和 std::mutex 类。std::thread 可以创建新的线程,并执行指定的函数或 Lambda 表达式,std::mutex 则可以保护共享资源,避免多个线程同时访问和修改同一个变量。

示例代码

复制代码
std::mutex mtx;
int count = 0;

std::vector<std::thread> threads;

for (int i = 0; i < 10; ++i) {
    threads.emplace_back([&]() {
        std::lock_guard<std::mutex> lock(mtx); // 使用互斥量保护共享资源
        count++;
    });
}

for (auto& thread : threads) {
    thread.join();
}

std::cout << "count: " << count << std::endl;

7.其他特性

C++14 和 C++17 标准引入了更多的改进和增强,如通用 lambda、变长模板、constexpr 函数、初始化列表等。通用 lambda 允许我们对任意类型的参数进行操作,变长模板则可以支持任意数量和任意类型的模板参数,constexpr 函数可以在编译时计算结果,初始化列表则可以方便地对复杂对象进行初始化。

八、案例:实现一个简单的并发下载器

cs 复制代码
#include <iostream>
#include <vector>
#include <thread>
#include <mutex>

std::mutex mtx;

void downloadFile(const std::string& url, const std::string& filename) {
    // 模拟下载文件的耗时操作
    std::this_thread::sleep_for(std::chrono::seconds(2));

    // 使用互斥量保护共享资源
    std::lock_guard<std::mutex> lock(mtx);
    std::cout << "Downloaded file: " << url << " saved as: " << filename << std::endl;
}

int main() {
    std::vector<std::string> urls = {
        "http://example.com/file1.txt",
        "http://example.com/file2.txt",
        "http://example.com/file3.txt"
    };

    std::vector<std::thread> threads;

    for (const auto& url : urls) {
        threads.emplace_back([&]() {
            // 生成文件名
            std::string filename = "file_" + std::to_string(std::hash<std::string>()(url)) + ".txt";
            downloadFile(url, filename);
        });
    }

    for (auto& thread : threads) {
        thread.join();
    }

    return 0;
}

具体而言,程序首先定义了一个包含多个 URL 的 std::vector 对象 urls,这些 URL 表示需要下载的文件地址。然后我们创建了一个 std::vector 对象 threads,用于存储多个线程对象。接着我们使用 for 循环遍历 urls,每次循环都会创建一个新的线程,并将其加入到 threads 中。每个线程都会调用 downloadFile 函数进行文件下载,同时生成一个唯一的文件名。

downloadFile 函数模拟了文件下载的耗时操作,具体而言,我们使用了 std::this_thread::sleep_for 函数,让线程休眠 2 秒钟,模拟文件下载的过程。在函数结束之前,我们使用 std::lock_guardstd::mutex 对共享资源进行了保护,确保每个线程都能够正确地输出下载完成的信息。

以上是一个简单的并发下载器示例。我们使用了 C++11 的并发编程支持,通过创建多个线程并发地下载多个文件。每个线程都会调用 downloadFile 函数进行文件下载,而该函数会使用互斥量保护共享资源,避免多个线程同时访问和修改同一个文件。

通过这个案例,我们可以看到 C++11 的并发编程支持非常强大,可以方便地实现多线程的应用程序,提高程序的性能和效率。同时,使用互斥量等工具可以保证多线程的安全性,避免竞态条件和数据竞争的问题。

相关推荐
知识分享小能手3 分钟前
React学习教程,从入门到精通, React 属性(Props)语法知识点与案例详解(14)
前端·javascript·vue.js·学习·react.js·vue·react
汇能感知2 小时前
摄像头模块在运动相机中的特殊应用
经验分享·笔记·科技
阿巴Jun3 小时前
【数学】线性代数知识点总结
笔记·线性代数·矩阵
茯苓gao3 小时前
STM32G4 速度环开环,电流环闭环 IF模式建模
笔记·stm32·单片机·嵌入式硬件·学习
是誰萆微了承諾3 小时前
【golang学习笔记 gin 】1.2 redis 的使用
笔记·学习·golang
利刃大大3 小时前
【高并发内存池】五、页缓存的设计
c++·缓存·项目·内存池
DKPT4 小时前
Java内存区域与内存溢出
java·开发语言·jvm·笔记·学习
aaaweiaaaaaa4 小时前
HTML和CSS学习
前端·css·学习·html
ST.J4 小时前
前端笔记2025
前端·javascript·css·vue.js·笔记
C语言小火车4 小时前
【C++八股文】基础知识篇
c++·tcp/ip·const·智能指针·多线程同步·static关键字·c++内存模型