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

news2024/11/19 8:37:23

文章目录

  • C++11简介
  • 列表初始化
    • std::initializer_list
  • 变量类型推导
  • nullptr
  • 范围for循环
  • STL中的一些变化

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中的重点内容,以下系列博客中会进行详细讲解.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/517026.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

怎么在照片上添加logo

怎么在照片上添加logo&#xff1f;现在是全面自媒体的时代&#xff0c;很多旅行博主或者摄影爱好者喜欢将自己拍摄的照片发布到各大平台上&#xff0c;分享自己的摄影作品&#xff0c;不过互联网属于一个开放平台&#xff0c;所以盗取照片的事情时有发生&#xff0c;很多不法分…

LabVIEWCompactRIO 开发指南16 有效使用网络共享变量的技巧

LabVIEWCompactRIO 开发指南16 有效使用网络共享变量的技巧 在使用网络共享变量进行编程时&#xff0c;可以遵循三个技巧来最大化性能并避免任何不需要的行为。图4.11显示了包含每个技巧的初始化过程。 技巧1:初始化共享变量 在应用程序开始时将共享变量初始化为已知值。如…

全文检索-Elasticsearch-整合SpringBoot

文章目录 前言一、整合检索服务1.1 创建 gulimall-search 模块1.2 配置 Maven 依赖1.3 搜索服务注册到注册中心1.4 新增 es 配置类1.5 测试 RestHighLevelClient 组件 二、存储数据到 ES2.1 测试 ES 简单插入数据2.2 测试 ES 查询复杂语句2.3 读入数据 前言 前面记录了 Elasti…

如何修复d3dcompiler_47.dll缺失?多种解决方法分享

在使用Windows操作系统的过程中&#xff0c;有时候会遇到d3dcompiler_47.dll缺失的情况。这个问题可能会导致某些应用程序无法正常运行&#xff0c;因此需要及时解决。本文将介绍如何修复d3dcompiler_47.dll缺失的问题。 一.什么是d3dcompiler_47.dll D3dcompiler_47.dll是Di…

Kali-linux查看打开的端口

对一个大范围的网络或活跃的主机进行渗透测试&#xff0c;必须要了解这些主机上所打开的端口号。在Kali Linux中默认提供了Nmap和Zenmap两个扫描端口工具。为了访问目标系统中打开的TCP和UDP端口&#xff0c;本节将介绍Nmap和Zenmap工具的使用。 4.4.1 TCP端口扫描工具Nmap 使…

revit的附着顶部/底部工具使用及CAD图纸转柱

一、revit的附着顶部/底部工具的使用 生活上&#xff0c;有很多建筑是斜屋顶的房子&#xff0c;像是一些别墅的装修&#xff0c;斜屋顶往往比平屋顶更有装饰感&#xff0c;也更有利于排水。 那么在Revit中&#xff0c;绘制带有斜屋顶的往往会遇到这样一个问题&#xff0c;屋顶之…

OpenCL编程指南-3.2OpenCL上下文

OpenCL上下文 上下文是所有OpenCL应用的核心。上下文为关联的设备、内存对象&#xff08;例如&#xff0c;缓冲区和图像&#xff09;以及命令队列&#xff08;在上下文和各设备之间提供一个接口&#xff09;提供了一个容器。正是上下文驱动着应用程序与特定设备以及特定设备之…

算法训练Day53:​ 1143.最长公共子序列 1035.不相交的线 53.最大子序和 动态规划

文章目录 最长公共子序列题解 不相交的线题解 最大子数组和题解 最长公共子序列 CategoryDifficultyLikesDislikesContestSlugProblemIndexScorealgorithmsMedium (64.94%)13110--0 Tags Companies 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长 公共子…

浏览csdn博客自动隐藏侧边栏并只看目录

背景 CSDN 总算做了点好事&#xff0c;能够隐藏大部分无关信息&#xff0c;只看博客内容本身。具体如图&#xff0c;还在测试版 以我的一篇博客为例&#xff0c;原始界面&#xff0c;花里胡哨一堆 点击隐藏侧栏后的清爽版 点击只看目录后的清爽版 前提提要 安装油猴脚本&…

使用VSCode创建Vue项目

Vue介绍 Vue.js是一个渐进式JavaScript框架&#xff0c;用于构建用户界面。它可以与其他库或现有项目集成&#xff0c;也可以作为单个组件使用。Vue.js的目标是提供一种简单、快速和灵活的方式来开发交互式Web应用程序。 Vue.js的核心特性包括&#xff1a; 响应式数据绑定&am…

http协议格式

HyperText Transfer Tansfer Protocol 超文本传输协议&#xff0c;是一种基于TCP的应用层协议&#xff0c;也是目前为止最为流行的应用层协议之一&#xff0c;可以说HTTP协议是万维网的基石。历经了0.9、HTTP/1.0、HTTP/1.1、HTTP/2几个版本(关于HTTP协议的历史&#xff0c;这里…

unity-物体rotation翻转180度后,OnPointerDown失效的问题

问题&#xff1a;今天碰到一个问题&#xff0c;就是把物体A进行水平翻转后&#xff0c;如下图&#xff0c;OnPointerDown 就失效了 》解决方案1&#xff08;使用Scale X来替代Rotation Y&#xff09;&#xff1a; 使用Scale改为-1来翻转&#xff0c;这样 OnPointerDown 就正常…

双向链表刷题总结

剑指 Offer 36. 二叉搜索树与双向链表 输入一棵二叉搜索树&#xff0c;将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点&#xff0c;只能调整树中节点指针的指向。 为了让您更好地理解问题&#xff0c;以下面的二叉搜索树为例&#xff1a; 我们希望将这…

分布式系统中的那些一致性(CAP、BASE、2PC、3PC、Paxos、ZAB、Raft)

本文介绍 CAP、BASE理论的正确理解、Paxos 算法如何保证一致性及死循环问题、ZAB 协议中原子广播及崩溃恢复以及 Raft 算法的动态演示。 下面还有投票&#xff0c;一起参与进来吧&#x1f44d; 文章目录 前言CAP理论理解误导正确的理解CAP理论的应用 BASE理论Paxos算法如何保证…

ASEMI代理LT6230CS6-10#TRPBF原装ADI车规级LT6230CS6-10#TRPBF

编辑&#xff1a;ll ASEMI代理LT6230CS6-10#TRPBF原装ADI车规级LT6230CS6-10#TRPBF 型号&#xff1a;LT6230CS6-10#TRPBF 品牌&#xff1a;ADI /亚德诺 封装&#xff1a;SOT-6 批号&#xff1a;2023 安装类型&#xff1a;表面贴装型 引脚数量&#xff1a;6 工作温度:-4…

sentinel介绍

介绍 官网地址 Sentinel 和 Hystrix 的原则是一致的: 当调用链路中某个资源出现不稳定&#xff0c;例如&#xff0c;表现为 timeout&#xff0c;异常比例升高的时候&#xff0c;则对这个资源的调用进行限制&#xff0c;并让请求快速失败&#xff0c;避免影响到其它的资源&…

阿里云争食币圈

阿里云的触手正在向币圈延伸。几天前&#xff0c;阿里云与Avalanche区块链和MUA DAO联合推出Cloudverse&#xff0c;为想要在链上部署元宇宙的企业提供一站式解决方案。 Avalanche是典型的币圈项目&#xff0c;链上的一切价值流转都以加密货币结算。此次合作释放出阿里云在Web…

apt 与 dpkg 命令详解

一. apt & dpkg 异同点 1. apt 与 dpkg 均为 ubuntu 下面的包管理工具。 2. dpkg 仅用于安装本地的软件包&#xff0c;安装时不会安装依赖包&#xff0c;不解决依赖问题。 sudo dpkg -i <package_name>.deb 3. apt 默认会从远程仓库搜索包的名字&#xff0c;下载并安…

多元线性回归——自相关(二)

自相关问题 文章目录 自相关问题(R)[toc]1 什么是自相关2 自相关产生的原因3 自相关的后果4 自相关检验5 自相关补救6 R语言操作 1 什么是自相关 经典普通最小二乘法估计的假设之一是扰动项不存在自相关&#xff0c;即对于 ∀ i ≠ j \forall i\ne j ∀ij,都有 C o v ( μ …

Kali-linux测试网络范围

测试网络范围内的IP地址或域名也是渗透测试的一个重要部分。通过测试网络范围内的IP地址或域名&#xff0c;确定是否有人入侵自己的网络中并损害系统。不少单位选择仅对局部IP基础架构进行渗透测试&#xff0c;但从现在的安全形势来看&#xff0c;只有对整个IT基础架构进行测试…