《C++ Primer Plus》第18章:探讨 C++ 新标准(7)
C++11 新增的其他功能
C++11 增加了很多功能,本书无法全面介绍;另外,本书编写期间,其中很多功能还未得到广泛实现。然而,有些功能有必要简要地介绍一下。
并行编程
当前,为提高计算机性能,增加处理器数量比提高处理器速度更容易。因此,装备了双核、四核处理器甚至多个多核处理器的计算机很常见,这让计算机能够同时执行多个线程,其中一个处理器可能处理视频下载,而另一个处理器处理电子表格。
有些操作能受益于多线程,但有些不能。考虑单向链表的搜索:程序必须从链表头开始,沿链接依次向下搜索,直到到达链表末尾;在这种情况下,多线程的帮助不大。再来看未经排序的数组。考虑到数组的随机存取特征,可让一个线程从数组开头开始搜索,并让另一个线程从数组中间开始搜索,这将让搜索时间减半。
多线程确实带来了很多问题。如果一个线程挂起或两个线程试图同时访问同一项数据,结果将如何呢?为解决并行性问题,C++ 定义了一个支持线程化执行的内存模型,添加了关键字 thread_local,提供了相关的库支持。关键字 thread_local 将变量声明为静态存储,其持续性与特定线程相关;即定义这种变量的线程过期时,变量也将过期。
库支持由原子操作(atomic operation)库和线程支持库组成,其中原子操作库提供了头文件 atomic,而线程支持库提供了头文件 thread、mutex、condition_variable 和 future。
新增的库
C++11 添加了多个专用库。头文件 random 支持的可扩展随机数库提供了大量比 rand() 复杂的随机数工具。例如,您可以选择随机数生成器和分布状态,分布状态包括均匀分布(类似于 rand()、二项分布和正态分布等。
头文件 chrono 提供了处理时间间隔的途径。
头文件 tuple 支持模板 tuple。tuple 对象是广义的 pair 对象。pair 对象可存储两个类型不同的值,而 tuple 对象可存储任意多个类型不同的值。
头文件 ratio 支持的编译截短有理数算术库让您能够准确地表示任何有理数,其分子和分母可用最宽的整型表示。它还支持对这些有理数进行算术运算。
在新增的库中,最有趣的一个是头文件 regex 支持的正则表达式库。正则表达式指定了一种模式,可用于与文本字符串的内容匹配。例如,方括号表达式与方括号中的任何单个字符匹配,因此[cCkK] 与 c、C、k 和 K 都匹配,而[cCkK] at 与单词 cat、Cat、kat 和 Kat 都匹配。其他模式包括与一位数字匹配的 \d、与一个单词匹配的 \w、与制表符匹配的 \t 等。在 C++ 中,斜杠具有特殊含义,因此对于模式 \d\t\w\d(即依次为一位数字、制表符、单词和一位数字),必须写成字符字面量“\d\t\w\d”,即使用\表示\。这是引入原始字符串的原因之一(参见第4章),它让您能够将该模式写成 R"\d\t\w\d"。
ed、grep 和 awk 等 UNIX 工具都使用正则表达式,而解释型语言 Perl 扩展了正则表达式的功能。C++ 正则表达式库让您能够选择多种形式的正则表达式。
低级编程
低级编程中的“低级”指的是抽象程度,而不是编程质量。低级意味着接近于计算机硬件和机器语言使用的比特和字节。对嵌入式编程和改善操作的效率而言,低级编程很重要。C++11 给低级编程人员提供了一些帮助。
变化之一是放松了 POD(Plain Old Data)的要求。在 C++98 中,POD 是标量类型(单值类型,如 int 或 double)或没有构造函数、基类、私有数据、虚函数等的老式结构。以前的理念是,POD 是可安全地逐字节复制的东西。这种理念没变,但 C++11 认识到,在满足 C++98 的某些约束的情况下,仍可以是合法的 POD。这有助于低级编程,因为有些低级操作(如使用C语言函数进行逐字节复制或二进制I/O)要求处理对象为 POD。
另一项修改是,允许共用体的成员有构造函数和析构函数,这让共用体更灵活;但保留了其他一些限制,如成员不能有虚函数。在需要最大程度地减少占用的内存时,通常使用共用体;上述新规则在这些情况下给程序员有更大的灵活性和功能。
C++11 解决了内存对齐问题。计算机系统可能对数据在内存中的存储方式有一定的限制。例如,一个系统可能要求 double 值的内存地址为偶数,而另一个系统可能要求其起始位置为 8 的整数倍。要获悉有关类型或对象的对齐要求,可使用运算符 alignof() (参见附录E)。要控制对齐方式,可使用说明符 alignas。
constexpr 机制让编译器能够在编译阶段计算结果为常量的表达式,让 const 变量可存储在只读内存中,这对嵌入式编程来说很有用(在运行阶段初始化的变量存储在随机访问内存中)。
杂项
C99 引入了依赖于实现的扩展模型,C++11继承了这种传统。在使用128位整数的系统中,可使用这样的类型。在 C 语言中,扩展类型由头文件 stdint.h支持,而在 C++ 中,为头文件 cstdint。
C++11 提供了一种创建用户自定义字面量的机制:字面量运算符(literal operator)。使用这种机制可定义二进制字面量,如 1001001b。相应的字面量运算符将把它转换为整数值。
C++ 提供了调试工具 assert。这是一个宏,它在运行阶段对断言进行检查,如果为 true,则显示一条消息,否则调用 abort()。断言通常是程序员认为在程序的某个阶段应为 true 的东西。C++11 新增了关键字 static_assert,可用于在编译阶段对断言进行测试。这样做的目的在于,对于在编译阶段(而不是运行阶段)实例化的模板,调试起来将更简单。
C++11 加强了对元编程(metaprogramming)的支持。元编程指的是编写这样的程序,它创建或修改其他程序,甚至修改自身。在 C++ 中,可使用模板在编译阶段完成这种工作。
语言变化
计算机语言是如何成长和发展的呢?C++的使用范围足够广后,显然需要国际标准,并将其控制权交给标准委员会:最初是 ANSI 委员会,随后是 ISO/ANSI 联合委员会,当前是 ISO/IEC JTCI/SC22/WG21(C++标准委员会)。ISO 是国际标准组织,IEC 是国际电子技术委员会,JEC1 是前两家组织组建的联合技术为鸢尾 1, SC22 是 JTC1 下属的编程语言委员会,而 WG21 是 SC22 下属的 C++ 工作小组。
委员会考虑缺陷报告和有关语言修改和扩展的提议,并试图达成一致。这个过程既繁琐又漫长,《The Dsign and Evolution of C++》(Stroustrup,Addison-Wesley,1994)介绍了这方面的一些情况。寻求一致的委员会沉闷而争议不断,可能不是鼓励创新的好方式,这也不是标准委员会应扮演的角色。
但就 C++ 而言,还有另外一种变更的途径,那就是充满创意的 C++ 编程社区的直接行动。程序员无法不受羁绊地改进语言,但可创建有用的库。设计良好的库可改善语言的用途和功能,提高可靠性,让编程更容易、更有乐趣。库是在现有语言功能的基础上创建的,不需要额外的编译器支持。如果库是通过模板实现的,则可以头文件(文本文件)的方式分发。
一项这样的变革是 STL,它主要是 Alexander Stepanov 创建的,Hewlett-Packard 免费提供它。STL 在编程社区获得了巨大成功,成了第一个 ANSI/ISO 标准的候选内容。事实上,其设计影响新标准的其他方面。
Boost 项目
最近,Boost 库成了 C++ 编程的重要部分,给 C++11 带来了深远影响。Boost 项目发起于 1998 年,当时的 C++ 库工作小组主席 Beman Dawes 召集其他几位小组成员指定了一项计划,准备在标准委员会的框架外创建新库。该计划的基本理念是,创建一个充当开放论坛的网站,让人发布免费的 C++ 库。这个项目提供有关许可和编程实践的指南,并要求对提议的库进行同行审阅。其最终的成果是,一系列得到高度赞扬和广泛使用的库。这个项目提供了一个环境,让编程社区能够检验和评估编程理念以及提供反馈。
TR1
TR1(Technical Report 1)是 C++ 标准委员会的部分成员发起的一个项目,它是一个库扩展选集,这些扩展与 C++98 标准兼容,但不是必不可少的。这些扩展是下一个 C++ 标准的候选内容。TR1 库让 C++ 社区能够检验其组成部分的价值。当标准委员会将 TR1 的大部分内容融入 C++11 时,面对的是众所皆知且经过实践检验的库。
在 TR1 中,Boost 库占了很大一部分。这包括模板类 tuple 和 array、模板 bind 和 function、智能指针(对名称和实现做了一定的修改)、static_assert、regex 库 和 random 库。另外,Boost 社区和 TR1 用户的经验也导致了实际的语言变更,如异常规范的摒弃和可变参数模板的添加,其中可变参数模板让 tuple 模板类和 function 模板的实现更好了。
使用 Boost
虽然在 C++11 中,可访问 Boost 开发的众多库,但还有很多其他的 Boost 库。例如,Conversion 库中的 lexical_cast 让您能够在数值和字符串类型之间进行简单地转换,其语法类似于 dynamic_cast:将模板参数指定为目标类型。下面的程序是一个简单示例:
// lexcast.cpp -- simple cast from float to string
#include<iostream>
#include<string>
#include"boost/lexical_cast.hpp"int main() {using namespace std;cout << "Enter your weight: ";float weight;cin >> weight;string gain = "A 10% increase raises ";string wt = boost::lexical_cast<string>(weight);gain = gain + wt + " to "; // string operator+()weight = 1.1 * weight;gain = gain + boost::lexical_cast<string>(weight) + ".";cout << gain << endl;return 0;
}
下面是两次运行该程序的情况:
Enter your weight: 150
A 10% increase raises 150 to 165.Enter your weight: 156
A 10% increase raises 156 to 171.600006.
第二次运行的结果凸显了 lexical_cast 的局限性:它未能很好地控制浮点数的格式。为控制浮点数的格式,需要使用更精致的内核格式化工具,这在第17章讨论过。
还可以使用 lexical_cast 将字符串转换为数值。
显然,Boost 提供的功能比这里介绍的要多得多。例如,Any 库让您能够在 STL 容器中存储一系列不同类型的值和对象,方法是将 Any 模板用作各种值的包装器。Math 库在标准 math 库的基础上增加了数学函数。Filesystem 库让您编写的代码可在使用不同文件系统的平台之间移植。有关这个库以及如何将其加入到各种平台的更详细消息,请参阅 Boost 网站(www.boost.org)。另外,有些 C++ 编译器(如 Cygwin 编译器)还自带了 Boost 库。
接下来的任务
如果仔细阅读了本书,则应很好地掌握了 C++ 的规则。然而,这仅仅是学习这种语言的开始,接下来需要学习如何高效地使用该语言,这样的路更长。最好的情况是,工作或学习环境让您能够接触优秀地 C++ 代码和程序员。另外,了解 C++ 后,便可以阅读一些介绍高级主题和面向对象编程的书籍,附录 H 列出了一些这样的资源。
OOP 有助于开发大型项目,并提高其可靠性。OOP 方法的基本活动之一是发明能够表示正在模拟的情形(被称为问题域(problem domain))的类。由于实际问题通常很复杂,因此找到适当的类富有挑战性。创建复杂的系统时,从空白开始通常不可行,最好采用逐步迭代的方式。为此,该领域的实践者开发了多种技术和策略。具体地说,重要的是在分析和设计阶段完成尽可能多的迭代工作,而不要不断地修改实际代码。
常用的技术有两种:用例分析(use-case analysis)和 CRC 卡(CRC card)。在用例分析中,开发小组列出了常见的使用方式或最终系统将用于的场景;找出元素、操作和职责,以确定可能要使用的类和类特性。CRC(Class/Responsibilities/Collaborators 的简称)卡片是一种分析场景的简单方法。开发小组为每个类创建索引卡片,卡片上列出了类名、类责任(如表示的数据和执行的操作)以及类的协作者(如必须与之交互的其他类)。然后,小组使用 CRC 卡片提供的接口模拟场景。这可能提出新的类、转换责任等。
在更大的规模上,是用于整个项目的系统方法。在这方面,最新的工具是统一建模语言(Unified Modeling Language,UML),它不是一种编程语言,而是一种用于表示编程项目的分析和设计语言,是由 Grady Booch、Jim Rumbaugh 和 Ivar Jacobson 开发的,他们分别是更早的 3 种建模语言(Booch Method、OMT(对象建模技术,Object Modeling Technique)和 OOSE(面向对象的软件工程,Object-Oriented Software Engineering))的主要开发人员。UML 是从这3种语言演化而来的,于2005年被 ISO/IEC 批准为标准。
除加深对 C++ 的总体理解外,还可能需要学习特定的类库。例如,Microsoft 和 Embracadero 提供了大量简化 Windows 编程的类库,而 Apple Xcode 提供了简化 Apple 平台(如 iPhone)编程的类库。
总结
C++新标准新增了大量功能。有些旨在让 C++ 更容易学习和使用,这包括用大括号括起的统一的列表初始化、使用 auto 自动推断类型、类内成员初始化以及基于范围的 for 循环;而有些旨在增强类设计以及使其更容易理解,这包括默认的和禁用的方法、委托构造函数、继承构造函数以及让虚函数设计更清晰的说明符 override 和 final。
有几项改进旨在提供程序和编程效率。lambda 表达式比函数指针和函数符更好,模板 function 可用于减少模板实例数量,右值引用让您能够使用移动语义以及实现移动构造函数和移动赋值运算符。
其他改进提供了更佳的工作方式。作用域内枚举让您能够更好地控制枚举的作用域和底层类型;模板 unique_ptr 和 shared_ptr 让您能够更好地处理使用 new 分配的内存。
新增的 decltype、返回类型后置、模板别名和可变参数模板让模板设计得到了改进。
修改后的共用体 和 POD 规则、alignof() 运算符、alignas 说明符以及 constexpr 机制支持低级编程。
新增了多个库(包括新的 STL 类、tuple 模板 和 regex 库)为众多常见的编程问题提供了解决方案。
为支持并行编程,新标准还添加了关键字 thread_local 和 atomic 库。
总之,无论对新手还是专家来说,新标准都改善了 C++ 的可用性和可靠性。
相关文章:
《C++ Primer Plus》第18章:探讨 C++ 新标准(7)
C11 新增的其他功能 C11 增加了很多功能,本书无法全面介绍;另外,本书编写期间,其中很多功能还未得到广泛实现。然而,有些功能有必要简要地介绍一下。 并行编程 当前,为提高计算机性能,增加处…...
Redis学习(二):Redis安装测试
概述 Redis是什么 Redis, Remote Dictionary Server, 即远程字典服务。免费开源的数据库。 由C语言编写,支持网络,可基于内存亦可持久化的日志型、KV数据库,并提供所种语言的API。 Redis能干嘛 用于内存存储,持久化。rdb、ao…...
Vector - CAPL - 简介及数据结构
对于想进入车载行业或者已经在车载行业工作的朋友对于CAPL这个词都会相当的熟悉,都知道他是做车载网络测试脚本的语言,并且跟C有点类似,但是它到底是什么呢?CAPL全称(Communication Access Programming Language&#…...
20230304英语学习
What Would Happen if the Moon Disappeared Tomorrow? 如果明天月球消失了会怎样? The closest object to our planet, the Moon, may seem like Earth’s little sibling.Since its birth, the satellite has mostly just hung around, playing gravitational t…...
【基础算法】单链表的OJ练习(3) # 移除链表元素 # 相交链表 #
文章目录前言移除链表元素相交链表写在最后前言 本章的OJ练习也是相对简单的,只要能够理解解题的思路,并且依照这个思路能够快速的写出代码,我相信,你的链表水平已经足够了。 对于OJ练习(2) : ->传送门…...
【自用】SpringBoot项目通用类整理
文章目录全局Json序列化Controller日志切面全局异常拦截GlobalExceptionHandlerApiResultBusinessExceptionResponseEntityUtil全局返回体包装MP自动填充接口文档配置类自定义Async异步线程池本文主要整理各类项目中通用的配置类、工具类,便于复查自用。 全局Json序…...
动态规划法(总述)多阶段决策最优化问题
动态规划: 研究最优控制问题提出的 该问题有n个输入,问题的解由这n个输入组成,这个子集必须满足事先给定的条件,这些条件称为约束条件,满足约束条件的可行解可能不只有一个为了衡量可行解的优劣,通常以一些函数的形式&…...
MySQL跨服务器数据映射
MySQL跨服务器数据映射环境准备1. 首先是要查看数据库的federated引擎 开启/关闭 状态2. 打开任务管理器,并重启mysql服务3. 再次查看FEDERATED引擎状态,引擎已启动映射实现问题总结在日常的开发中经常进行跨数据库进行查询数据。 同服务器下跨数据库进…...
利用反射实现通过读取配置文件对类进行实例化-课后程序(JAVA基础案例教程-黑马程序员编著-第十二章-课后作业)
【案例12-3】:利用反射实现通过读取配置文件对类进行实例化 【案例介绍】 1.案例描述 现在有一个项目,项目中创建了一个Person类,在Person类中定义了一个sleep()方法。在工程中还定义了一个Student类继承Person类,在Student类中…...
1.2 CSS文本属性
CSS Text(文本)属性: 定义文本外观,颜色,装饰,缩进,行间距来修饰文本 文本样式 文本缩进 text-indent文本水平对齐方式:text-align文本修饰:text-decoration行高 line-height CSS文本颜色属性…...
SpringCloud之认识微服务
文章目录一、传统项目转型二、走进 SpringCloud三、微服务项目搭建3.1 创建一个 SpringBoot 项目3.2 创建三个 Maven 子工程3.3 为子工程创建 application.yml3.4 引入依赖3.5 数据库 建库建表3.6 编写业务提示:以下是本篇文章正文内容,SpringCloud系列学…...
【go语言之thrift协议二之server端分析】
go语言之thrift协议二serverthrift.TProtocolFactoryTTransportReadWriteCloserContextFlusherReadSizeProviderTProtocolrunServerNewTServerSocketNewCalculatorHandlerNewCalculatorProcessorNewTSimpleServer4server.ServeListenAcceptLoopprocessRequests在上一篇文章分析…...
【办公类05-03】Python批量修改文件名前面的序号(已有的序号错了,需要改成正确的号码)
背景需求下载教程,手动输入编号,有一个编号错误,导致后面所有编号都错了。30实际是29,以此类推怎样才能快速修改编号数字?前期考虑到可能要改编号,所以在每个编号后面加“ ”(空格)&…...
定向模糊测试工具Beacon基本用法
Beacon是一个定向模糊测试工具,给定行号,能够定向探索行号附近的代码区域。主要思想是采用静态分析的方法获取到与目标有关的变量的最弱前置条件(weakest precondition)的信息,并在相关位置插入断言,来提前…...
《程序员面试金典(第6版)》面试题 02.01. 移除重复节点
题目描述 编写代码,移除未排序链表中的重复节点。保留最开始出现的节点。 示例1: 输入:[1, 2, 3, 3, 2, 1] 输出:[1, 2, 3] -示例2: 输入:[1, 1, 1, 1, 2] 输出:[1, 2] 提示: 链表长度在[0, 20000]范…...
如何对web系统开展无障碍测试
Accessibility test(无障碍测试)是一种测试方法,旨在评估软件、网站或其他数字产品的可访问性,以确保它们能够被身体残障或其他特殊需求的用户使用。这些测试通常包括使用辅助技术,如屏幕阅读器和放大器,以…...
使用vite+vue3.0 创建一个cesium基础应用 ----01 项目搭建
使用vitevue3.0 创建一个cesium基础应用 ----01 项目搭建 1.使用yarn创建一个vite项目 我们可以在vite官网找到vite创建项目的命令 https://cn.vitejs.dev/ 可以使用yarn创建项目选择使用vue3.0框架,语言使用js 创建完成后结构如下: 2.找到vite社区中的…...
【Python学习笔记】第二十七节 Python 多线程
一、进程和线程进程:是程序的一次执行,每个进程都有自己的地址空间、内存、数据栈及其他记录运行轨迹的辅助数据。线程:所有的线程都运行在同一个进程当中,共享相同的运行环境。线程有开始、顺序执行和结束三个部分, …...
【id:18】【20分】B. DS顺序表--连续操作
题目描述建立顺序表的类,属性包括:数组、实际长度、最大长度(设定为1000)该类具有以下成员函数:构造函数:实现顺序表的初始化。插入多个数据的multiinsert(int i, int n, int item[])函数,实现在…...
vi编辑器操作指令分享
vi编辑器是所有Unix及Linux系统下标准的编辑器,它的强大不逊色于任何最新的文本编辑器,这里只是简单地介绍一下它的用法和一小部分指令。由于对Unix及Linux系统的任何版本,vi编辑器是完全相同的,因此您可以在其他任何介绍vi的地方…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
rknn优化教程(二)
文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...
《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...
Java + Spring Boot + Mybatis 实现批量插入
在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法:使用 MyBatis 的 <foreach> 标签和批处理模式(ExecutorType.BATCH)。 方法一:使用 XML 的 <foreach> 标签ÿ…...
深度学习水论文:mamba+图像增强
🧀当前视觉领域对高效长序列建模需求激增,对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模,以及动态计算优势,在图像质量提升和细节恢复方面有难以替代的作用。 🧀因此短时间内,就有不…...
