C++11 -- 入门基础知识

2023-11-01

C++11简介

  • 在2003年C++标准委员会曾经提交了一份技术勘误表(简称TC1),使得C++03这个名字已经取代了C++98称为C++11之前的最新C++标准名称。
  • 不过由于C++03(TC1)主要是对C++98标准中的漏洞进行修复,语言的核心部分则没有改动,因此人们习惯性的把两个标准合并称为C++98/03标准。
  • 从C++0x到C++11,C++标准10年磨一剑,第二个真正意义上的标准珊珊来迟。相比于C++98/03,C++11则带来了数量可观的变化,其中包含了约140个新特性,以及对C++03标准中约600个缺陷的修正,这使得C++11更像是从C++98/03中孕育出的一种新语言。
  • 相比较而言,C++11能更好地用于系统开发和库开发、语法更加泛华和简单化、更加稳定和安全,不仅功能更强大,而且能提升程序员的开发效率,公司实际项目开发中也用得比较多,所以我们要作为一个重点去学习.

小故事
1998年是C++标准委员会成立的第一年,本来计划以后每5年视实际需要更新一次标准C++国际标准委员会在研究C++ 03的下一个版本的时候,一开始计划是2007年发布,所以最初这个标准叫C++ 07。但是到06年的时候,官方觉得2007年肯定完不成C++ 07,而且官方觉得2008年可能也完不成。最后干脆叫C++ 0x。x的意思是不知道到底能在07还是08还是09年完成。结果2010年的时候也没完成,最后在2011年终于完成了C++标准。所以最终定名为C++11.

列表初始化

在C++98中,标准允许使用花括号{}对数组和结构体元素进行统一的列表初始值设定.比如:

struct Point
{
	int _x;
	int _y;
};
int main()
{
	int array1[] = { 1, 2, 3, 4, 5 };  //使用花括号对数组进行初始化.
	int array2[5] = { 0 };
	struct Point p = { 1, 2 };         //使用花括号对结构体进行初始化.
	return 0;
}

C++11扩大了用大括号括起的列表(初始化列表)的适用范围,使其可用于所有内置类型和用户自定义的类型,使用初始化列表时,可以添加等于号(=),也可以不添加.

对于内置类型:

struct Point
{
	int _x;
	int _y;
};
int main()
{
	int array1[] = { 1, 2, 3, 4, 5 };
	int array2[5] = { 0 };
	struct Point p = { 1, 2 };        

	int* p1 = new int[6]{ 0 };               //C++11中{}也可以作用域new表达式中

	int* p2 = new int[6]{ 1,2,3,4,5,6 };
	return 0;
}

对于自定义类型:
C++11支持的列表初始化,对于自定义类型会调用构造函数初始化.

class Date
{
public:
 Date(int year, int month, int day)
 :_year(year)
 ,_month(month)
 ,_day(day)
 {
 cout << "Date(int year, int month, int day)" << endl;
 }
private:
 int _year;
 int _month;
 int _day;
 }
 int main()
 {
      Date d1(2022,1,1);               //C++98
      Date d2{2022,1,2 };             //C++11
      Date d3{2022,1,3};              //C++11 
 }

std::initializer_list

C++中新增了begin和end容器,其本质为一个静态数组,主要成员函数如下:
1: 提供了begin()和end()函数,用于支持迭代器遍历.
2. 还提供了size()函数,用于获取容器数据个数.
在这里插入图片描述
其中,{ }也是一种模板类型,类型便为initializer_list类模板
在这里插入图片描述

STL中的所有容器支持使用initializer_list函数构造,所以STL容器中都支持使用列表初始化.当我们使用列表初始化时( {} ),实则是将initializer_list类模板具体类型传给initializer_list构造函数对应参数,此时,编译器便会调用该构造函数进行初始化.
在这里插入图片描述

怎么在我们模拟实现的vector中支持列表初始化?

我们可以在模拟实现的vector中添加initializer_list构造函数,当我们使用初始化列表初始化时,实则是将花括号中所有数据都放进了initializer类型对象的静态数组中,然后我们可以通过遍历该静态数组的数据,将数据一 一尾插到vector容器中.

vector(initializer_list<T> il)
			:_start(nullptr)
			, _finish(nullptr)
			, _end_of_storage(nullptr)
		{
			resize(il.size());
			for (auto& e : il)
			{
				push_back(e);
			}

		}

变量类型推导

decltype

这里与我们熟悉的auto有一些差异:

  • 关键字decltype可以将变量的类型声明为表达式指定的类型
  • auto关键字是编译器通过表达式右边的数据类型来推出左边的数据类型.
int main()
{
	int x = 10;

	decltype(x) y1 = 20.22;  //根据x推倒y
	
	auto y2 = 20.22;         //根据20.22推导y2.

	cout << y1 << endl;      //20

	cout << y2 << endl;      //20.22
	return 0;
}

注意:
通过typeid(变量名).name()只能获取一个变量类型的字符串,但无法根据它获取到的这个类型去定义变量.

nullptr

由于C++中NULL可以被定义成整型常量0,这样就可能会带来一些问题,因为0既能表示答指针常量,又能表示整型常量0.所以,出于清晰和安全的角度考虑,C++11中系中新增了nullptr,用于表示空指针.

以下为C++11中针对NULL定义类型:

/* Define NULL pointer value */
#ifndef NULL
#ifdef __cplusplus
#define NULL    0
#else  /* __cplusplus */
#define NULL    ((void *)0)
#endif  /* __cplusplus */
#endif  /* NULL */

当然,在大部分场景下,使用NULL和nullptr没什么差异,但是如果在一些极端情况的传参场景中可能会导致我们所不希望的结果.

void f(int ret)
{
	cout << "void f(int ret)" << endl;
}
void f(int* arg)
{
	cout << "void f(int* ret)" << endl;
}
int main()
{
	f(NULL);    //void f(int ret)
	f(nullptr); //void f(int* ret)
	return 0;
}

在我们的观念中,NULL和nullptr代表的都是空指针,所以我们都希望能够调用的是形参为int*的重载函数,可是,因为NULL又可以代表整型常量0,所以编译器就会去调用形参为int的重载函数.

void f(int arg)
{
	cout << "void f(int arg)" << endl;
}
void f(int* arg)
{
	cout << "void f(int* arg)" << endl;
}
int main()
{
	f(NULL);    //void f(int arg)
	f(nullptr); //void f(int* arg)
	return 0;
}

范围for循环

在C++98中,我们遍历数组常常通过以下方式:

int main()
{
	int arr[] = { 1,2,3,4,5,6 };
	
	for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); ++i)
	{
		arr[i] += 1;
	}

	for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); ++i)
	{
		cout << arr[i] << endl;
	}

	return 0;

}

可是,但是对于以上方式,不但麻烦,还容易将判断条件写错,基于以上情况,C++11引入了范围for, 冒号( : ) 左边表示每一次遍历目标数组(对象)中所需要的变量,冒号( : ),右边则表示需要遍历的数组(或者对象).

int main()
{
    int arr[] = { 1 , 2, 3, 4, 5, 6 };
    
    for (auto& e : arr)
    {
        e += 2;
    }

    for (auto& e : arr)
    {
        cout << e << endl;
    }
}

STL中的一些变化

新容器

C++11中新增了四个容器,分别是array,forward_list,unordered_map,unordered_set. 其中array,forward容器的作用比较鸡肋,unorder_map和unordered_set是一个亮点.
在这里插入图片描述
一: array容器

  • array的本质就是一个静态的顺序表经过包装成了容器.
  • array容器与数组最大的差别就是对于越界的检测严格很多.
int main()
{
	const size_t N = 5;
	
	int a1[N];          

	a1[N];             //越界读vsuai stdio测不出来.              

	a1[N] = 1;         //越界写可以测试出来.

	array<int, N> a2;
	
	//越界读写都可以被检查出来.
	a2[N]             
                            
	a2[N] = 2;

}

注意:
1: array之所以对越界检测很严格,因为它类似于vector容器,在使用[]访问元素时会进行针对于越界的断言检查.

2: array相对于其他容器来说,array是在栈上开辟空间的,不适合开辟特别大的数组,否则容易导致栈溢出.

二:forward_list

forward_list本质来讲就是一个单链表.

forward_list很少被人使用,原因如下:

(1): 相对于list双向链表来说,结点少存储了一个指针,但是只针对于大量数据处理节省空间效果较大.

(2): forward_list 只支持在头插头删,不支持尾插尾删.因为单链表在进行尾插尾删的时候需要找尾,时间复杂度为O(N);

(3): forward_list的插入函数(insert_after) 表示在指定元素的后面插入一个元素,而不是像其他容器在指定元素的前面插入一个元素(这点对于删除函数(erase_after)类似),这对于我们平常的使用来说有点违和.

三:unordered_map和unordered_set
unordered_map和unordered_set的本质来说都是哈希表,对于这两个容器,博主已经为其作了详细的讲解:
(1) 哈希表(底层结构剖析-- 上)

(2)哈希表(底层结构剖析–下)

(3) C++STL详解(十) – 使用哈希表封装unordered_set和unordered_map

内部变化

(1): STL容器都支持initializer_list构造,用来支持列表初始化.

(2): 提供了cbegin,cend方法,用于返回const迭代器,但是是比较鸡肋的,因为原本就支持普通对象调用普通迭代器,cons对象调用const迭代器就已经很方便了.

(3 ) 移动构造和移动赋值,提高效率,节省空间.

(4): 右值引用参数的插入.

说明:
(3),(4)也是C++11中的重点内容,以下系列博客中会进行详细讲解.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++11 -- 入门基础知识 的相关文章

  • VB.NET 相当于 C# 属性简写吗?

    是否有与 C 等效的 VB NET public string FirstName get set 我知道你能做到 Public Property name As String Get Return name ToString End Ge
  • std::cout 和 std::wcout 有什么区别?

    在c 中 有什么区别std cout and std wcout 它们都控制流缓冲区的输出或将内容打印到控制台 或者它们只是相似吗 它们作用于不同的字符类型 std cout uses char作为字符类型 std wcout uses w
  • 为 Visual Studio 2013 编译 Tesseract

    我正在尝试使用tesseract在 Visual Studio 2013 中 我在链接器 gt 输入 不是 libtesseract302 static lib 中使用 libtesseract302 lib 一切都正常 并且已编译并运行
  • 向 Nhibernate 发出 SQL 查询

    如何将此 SQL 查询发送给 Nhibernate SELECT Customer name FROM Company INNER JOIN Customer ON Company CompanyId Customer CompanyId
  • 单元测试一起运行时失败,单独运行时通过

    所以我的单元测试遇到了一些问题 我不能只是将它们复制并粘贴到这里 但我会尽力而为 问题似乎是 如果我一项一项地运行测试 一切都会按预期进行 但如果我告诉它一起运行测试 则 1 5 将通过 TestMethod public void Obj
  • 生成(非常)大的非重复整数序列而不进行预洗牌

    背景 我编写了一个简单的媒体客户端 服务器 我想生成一个不明显的时间值 随从客户端到服务器的每个命令一起发送 时间戳中将包含相当多的数据 纳秒分辨率 即使它不是真正准确 因为现代操作系统中计时器采样的限制 等 我想做的 在 Linux 上
  • C# Dns.GetHostEntry 不返回连接到 WiFi 的移动设备的名称

    我有一个 C 中的 Windows 窗体应用程序 我试图获取列表中所有客户端的主机名 下面给出的是 ra00l 来自此链接的代码示例 GetHostEntry 非常慢 https stackoverflow com questions 99
  • 使用 C 语言使用 strftime() 获取缩写时区

    我看过this https stackoverflow com questions 34408909 how to get abbreviated timezone and this https stackoverflow com ques
  • 单击 form2 上的按钮触发 form 1 中的方法

    我对 Windows 窗体很陌生 我想知道是否可以通过单击表单 2 中的按钮来触发表单 1 中的方法 我的表格 1 有一个组合框 我的 Form 2 有一个 保存 按钮 我想要实现的是 当用户单击表单 2 中的 保存 时 我需要检查表单 1
  • 将 Excel 导入到 Datagridview

    我使用此代码打开 Excel 文件并将其保存在 DataGridView 中 string name Items string constr Provider Microsoft Jet OLEDB 4 0 Data Source Dial
  • 未定义的行为或误报

    我 基本上 在野外遇到过以下情况 x x 5 显然 它可以在早期版本的 gcc 下编译干净 在 gcc 4 5 1 下生成警告 据我所知 警告是由 Wsequence point 生成的 所以我的问题是 这是否违反了标准中关于在序列点之间操
  • 未经许可更改内存值

    我有一个二维数组 当我第一次打印数组的数据时 日期打印正确 但其他时候 array last i 的数据从 i 0 到 last 1 显然是一个逻辑错误 但我不明白原因 因为我复制并粘贴了 for 语句 那么 C 更改数据吗 I use g
  • 在一个字节中存储 4 个不同的值

    我有一个任务要做 但我不知道从哪里开始 我不期待也绝对不想要代码中的答案 我想要一些关于该怎么做的指导 因为我感到有点失落 将变量打包和解包到一个字节中 您需要在一个字节中存储 4 个不同的值 这些值为 NAME RANGE BITS en
  • C++:.bmp 到文件中的字节数组

    是的 我已经解决了与此相关的其他问题 但我发现它们没有太大帮助 他们提供了一些帮助 但我仍然有点困惑 所以这是我需要做的 我们有一个 132x65 的屏幕 我有一个 132x65 的 bmp 我想遍历 bmp 并将其分成小的 1x8 列以获
  • Visual Studio 中的测试单独成功,但一组失败

    当我在 Visual Studio 中单独运行测试时 它们都顺利通过 然而 当我同时运行所有这些时 有些通过 有些失败 我尝试在每个测试方法之间暂停 1 秒 但没有成功 有任何想法吗 在此先感谢您的帮助 你们可能有一些共享数据 检查正在使用
  • 如何在 Blackberry Cascades 中显示具有特定号码的电话板

    我正在使用带有 C QT 和 QML 的 Blackberry Cascades 10 Beta 3 SDK 以及 Blackberry 10 Dev Alpha Simulator 和 QNX Momentics IDE 并且我正在尝试实
  • 如何在按钮单击时模拟按键 - Unity

    我对 Unity 中的脚本编写非常陌生 我正在尝试创建一个按钮 一旦单击它就需要模拟按下 F 键 要拾取一个项目 这是我当前的代码 在编写此代码之前我浏览了所有统一论坛 但找不到任何有效的东西 Code using System Colle
  • 英特尔 Pin 与 C++14

    问题 我有一些关于在 C 14 或其他 C 版本中使用英特尔 Pin 的问题 使用较新版本从较旧的 C 编译代码很少会出现任何问题 但由于 Intel Pin 是操作指令级别的 如果我使用 C 11 或 C 14 编译它 是否会出现任何不良
  • 防止在工厂方法之外实例化对象

    假设我有一个带有工厂方法的类 class A public static A newA Some code logging return new A 是否可以使用 a 来阻止此类对象的实例化new 那么工厂方法是创建对象实例的唯一方法吗 当
  • 在客户端系统中安装后桌面应用程序无法打开

    我目前正在使用 Visual Studio 2017 和 4 6 1 net 框架 我为桌面应用程序创建了安装文件 安装程序在我的系统中完美安装并运行 问题是安装程序在其他计算机上成功安装 但应用程序无法打开 edit 在客户端系统中下载了

随机推荐

  • blender快捷键

    tab 模式切换 可以shift多物体切换 主键盘 1点 2线 3面 按住shift 点击点面 可以多选 或者shift 1 2 3多选 ctrl alt q 四象视图 小键盘1前 3右 7顶 9切换前后 也可以按crl 1后视图 小键盘
  • STL系列之十 全排列(百度迅雷笔试题)

    转载自 http blog csdn net morewindows article details 7370155 全排列在笔试面试中很热门 因为它难度适中 既可以考察递归实现 又能进一步考察非递归的实现 便于区分出考生的水平 所以在百度
  • GlidedShy 第一题 实现自动登录和数据爬取

    python 自动登录 控制以及接管浏览器 爬取信息练习 GlidedShy官网 爬虫练习网站 代码仅供学习参考 功能实现步骤 自动登录 输入账号密码 选择题目 爬取数据 自动提交后返回 验证邮箱 注册时已人工验证 框架 Seleium控制
  • spdlog和fork冲突问题

    遇到个问题 使用spdlog的async logger打印日志 一直都是正常的 但是调用了fork之后就不打印了 先使用打印TODO大法 使用的spdlog的default logger打印 走的console打印 结果发现console打
  • win10 WSL2 Docker 与 Linux Docker

    项目场景 项目场景 用win10 wsl2 docker开发使用GPU tensorflow onnx TensorRT 的镜像 然后部署到Linux生产环境进行使用 发现不识别cuda驱动 问题描述 在Linux上运行wsl2 save
  • 优化算法基本原理

    优化算法基本原理 机器学习就两个问题 一个是model的定义 一个就是如何优化 model是战略 优化则是执行 在Caffe现在的版本中 主要使用了三种优化算法SGD AdaGrad 以及NAG 这三种算法快速 高效 缺点就是极容易收敛到局
  • iOS架构-组件化(项目实战-项目首页架构)

    UI架构设计 设计模式 外观模式 代理模式 适配器模式 adapter 注意 一版本只是搭建结构 一 1 0 Tab搭建 二 1 1 新增UICollectionView 主页 gt 整体设计基于 gt UICollectionView 滑
  • protobuf介绍和语法

    目录 前言 语法 标识符 字段 字段类型 proto2和proto3区别 前言 Protobuf即Protocol Buffers 是Google公司开发的一种跨语言和平台的序列化数据结构的方式 是一个灵活的 高效的用于序列化数据的协议 与
  • 用CSS实现宽度自适应100%,宽高比例为16: 9的矩形

    宽度自适应100 宽高比为16 9 即100 h 16 9 计算出来矩形高度 h 56 25 父元素设置height 0 padding bottom 56 25 是为了让子元素适应父元素的高度 子元素高度 父元素的 padding bot
  • python 崇天_python 从入门到放弃-----认识python的过程

    因为初来匝道 这样子写不知道会不会有问题 这里我先写下来 后期如果有问题 再修改 这里只记录一个小渣渣的学习过程和总结 中途学习爬虫也断断续续 还在继续努力中 但也总结自己的一些个人经验 1 零基础学习爬虫 还是要学python和HTML的
  • 2023年第二届服务机器人国际会议(ICoSR 2023)

    会议简介 Brief Introduction 2023年第二届服务机器人国际会议 ICoSR 2023 会议时间 2023年7月21日 23日 召开地点 中国 上海 大会官网 www iwosr org ICoSR 2023将围绕 服务机
  • Clang 新手教程来啦!

    长话短说 这篇新手教程会让你弄清楚什么是clang clang AST clang plugins 和clang tools 等等 让你大概知道clang 可以解决什么问题 而且小白也是可以用clang libraries 来开发工具的 0
  • 微信小程序前端引入weui组件库

    正在开发的微信小程序 想使用weui组件库 步骤如下 基础 1 小程序开发工具 1 06 22 1 初始化 以管理员身份运行命令行窗口 cmd 或使用VSCode进入终端 在cmd中进入项目的根目录 然后输入以下命令 npm init 后面
  • 2020新版去水印小程序搭建详细教程

    可以设置小程序跳转 引流也不错 支持小程序后台流量主激励视频广告 用户下载一次观看一次视频广告 收入非常可观 支持小程序后台流量主banner广告 支持全网短视频解析 苹果安卓通用 支持后台无限生成卡密 支持自定义文字广告 支持图片广告 支
  • amazon-kinesis-video-streams-webrtc-sdk-c 移植到linux开发板

    大部分参考这位大神的资料 分析依赖关系 通过分析Cmakelist txt得出了一些依赖关系 libkvsWebrtcClient so 依赖项如下 libkvspicUtils a libkvspicState a libssl so l
  • 如何写好一份PPT

    写工作汇报PPT 核心是 要让领导一眼看懂你做的汇报 PPT 本着这个原则 这里老秦提供4种解决方案 PowerPoint的核心作用是什么 Power your Point PPT 的第一目的是沟通和传达 它是架在讲者和听者之间的桥梁 辅助
  • 数字IC-序列检测-fsm

    序列检测简介及代码实现 序列检测器包含两种 一种是移位寄存器 另一种时状态机 还有重复序列和不重复序列检测 重点关注和了解如何用状态机去实现 序列检测器就是将指定的序列从数字码流 中检测出来 收到输出1 否则输出0 移位寄存器解法 重复序列
  • 教你如何安装SCSI硬盘 安装、启动、设置篇

    SCSI硬盘一向认为是昂贵且高不可攀的存储设备 不仅本身价位高于IDE硬盘很多 而且必须另外选择SCSI接口卡 因此在这样的条件下 一般计算机用户便倾向于使用IDE接口的硬盘 IDE硬盘虽然具有低价的优势 但始终敌不过SCSI硬盘的强悍速度
  • python算法中的深度学习算法之强化学习(详解)

    目录 学习目标 学习内容 强化学习 环境建模 Markov决策过程
  • C++11 -- 入门基础知识

    文章目录 C 11简介 列表初始化 std initializer list 变量类型推导 nullptr 范围for循环 STL中的一些变化 C 11简介 在2003年C 标准委员会曾经提交了一份技术勘误表 简称TC1 使得C 03这个名