C++11入门基础知识

news2024/11/20 22:40:48

文章目录

  • 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/495342.html

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

相关文章

阿里云Alibaba Cloud Linux镜像操作系统性能兼容如何?

阿里云服务器操作系统Alibaba Cloud Linux镜像怎么样&#xff1f;可以代替CentOS吗&#xff1f;Alibaba Cloud Linux兼容性如何&#xff1f;有人维护吗&#xff1f;漏洞可以修复吗&#xff1f;Alibaba Cloud Linux完全兼容CentOS&#xff0c;并由阿里云官方免费提供长期维护。 …

【五一创作】自动驾驶技术未来大有可为

本文概要 自动驾驶技术是当今汽车行业的发展热点之一&#xff0c;但其也存在着许多争议。大家也可以从以下几个维度谈谈你对这项技术的看法。 &#x1f31f;&#x1f31f;&#x1f31f;个人简介&#x1f31f;&#x1f31f;&#x1f31f; ☀️大家好&#xff01;我是新人小白博…

4.2 线性表顺序表(上)

目录 目录结构 线性表 线性表的特征&#xff1a; 顺序表存储结构的表示 顺序表存储结构的特点 顺序存储结构的表示 线性表的基本运算 基本运算的相关算法 线性表的基本运算 线性表 目录结构 线性表 线性表是包含若干数据元素的一个线性序列 记为&#xff1a; L(a0, …

Android FlexboxLayout布局

FlexboxLayout 布局 一、简介二、使用三、功能详解FlexboxLayout属性flexWrapflexDirectionalignItemsjustifyContentalignContentdividerDrawableHorizontal、showDividerHorizontaldividerDrawableVertical、showDividerVerticaldividerDrawable、showDividermaxLine Flexbox…

简单理解Transformer注意力机制

这篇文章是对《动手深度学习》注意力机制部分的简单理解。 生物学中的注意力 生物学上的注意力有两种&#xff0c;一种是无意识的&#xff0c;零一种是有意识的。如下图1&#xff0c;由于红色的杯子比较突出&#xff0c;因此注意力不由自主指向了它。如下图2&#xff0c;由于…

讯飞星火认知大模型 VS CHATGPT3.5

2023年5月6日&#xff0c;科大讯飞(002230.SZ)宣布将于当日举行“讯飞星火认知大模型”成果发布会。 与其他厂商的大模型发布相比&#xff0c;本次发布会具有三个特点&#xff1a;1.全程真机互动&#xff0c;现场实测、现场体验&#xff1b;2.技术先进性不是笼统表达&#xff…

Java的自定义注解

java元注解和自定义注解的区别 Java的自定义注解是一种元数据&#xff0c;可以应用于类、方法、字段等程序元素上&#xff0c;以提供额外的信息或指示。 自定义注解包括注解声明、元注解、运行时处理器三个部分。注解声明指定了注解的名称、作用域、成员等信息&#xff1b;元注…

IP-GUARD如何通过网络控制策略禁止应用程序联网?

如何通过网络控制策略禁止应用程序联网? 可以在控制台-高级-网络控制中,添加以下策略: 动作:“禁止” 应用程序:填写要禁止的程序(以QQ示例) 如何禁止没有安装客户端的电脑访问客户端电脑? 可以给所有客户端设置只允许客户端电脑访问的网络控制策略; 在控制台左边的…

Unity使用Sqlite3

环境 Unity:Unity2021.3.6f1c1 OS:Window10 64 Plugins:Mono.Data.Sqlite、Sqlite 插件准备 Sqlite3官方网址 Sqlite3有x64和x86版本&#xff0c;根据发布的架构使用不同版本的Sqlite3。 该文档使用x64版本&#xff0c;发布架构为64位。 Mono.Data.Sqlite 使用Unity Hub打开…

搜索旋转排序数组

题目链接 搜索旋转排序数组 题目描述 注意点 nums 中的每个值都 独一无二题目数据保证 nums 在预先未知的某个下标上进行了旋转 解答思路 因为本题数组基本递增&#xff08;仅在某个位置进行旋转&#xff09;&#xff0c;可以看作由两个递增的数组组合而成&#xff0c;所以…

OPenGL笔记--创建一个3D场景

文章目录 一、前言二、效果展示三、详细流程3.1、World.txt文件规则3.2、加载World.txt3.3、绘制场景3.4、交互 四、详细代码五、举一反三 一、前言 通过前面的学习&#xff0c;基本掌握了怎么绘制图形&#xff0c;使用纹理&#xff0c;接下来就来创建一个3D场景。 基本原理 …

Unity 软性管的实现

概述 因近期项目有要求使用到水管这种软性管的模拟&#xff0c;该篇主要说明软管的实现和应用&#xff0c;参考自&#xff1a;unity3D---实现柔软水管&#xff08;蛇的移动&#xff09;效果一&#xff08;无重力&#xff09;_unity 软管_ayouayouwei的博客-CSDN博客 效果 实现…

B/S医院手术麻醉管理系统源码:麻醉知情同意书模板

麻醉知情同意书模板 姓名:​ 性别:​ 年龄:​ 科别:​ 床号:​ 住院号:​ 疾病介绍和治疗建议: 医生已告知我因​手术&#xff0c;而接受麻醉。 1.麻醉作用的产生主要是利用麻醉药使中枢神经系统或神经中某些部位受到抑制的结果&#xff0c;临床麻醉的主要任务是: 2.为…

webpack 的打包流程

1.webpack 的打包流程 从以上5个方面来分析Webpack的打包流程&#xff1a; 初始化参数&#xff1a;这一步会从我们配置的webpack.config.js中读取到对应的配置参数和shell命令中传入的参数进行合并得到最终打包配置参数。 开始编译&#xff1a;这一步我们会通过调用webpack()方…

计算机网络基础知识(二)—— 什么是Ip地址、Mac地址、网关、子网掩码、DNS

文章目录 01 | Ip地址02 | Mac地址03 | 网关04 | 子网掩码05 | DNS06 | 总结 初次接触网络时&#xff0c;只知道电脑连接网线&#xff0c;就可以打开4399玩小游戏&#xff0c;可以登录QQ和朋友聊天&#xff1b; 再次接触网络时&#xff0c;知道了怎么查看自己电脑的网络情况&am…

06 - 5 生产者消费者模式

架构演进 介绍 同步调用变成异步调用生产数据与消费数据分离协调不同处理速度 生产者 系统运转的动力为下一个环节产生待处理的工作/数据与消费者的关系 重点在如何将数据发送到容器对消费者无依赖不关注消费者的how/when 发送顺序 消费者 容器 平衡 与EDA对比 消费策略 优点…

我发布了自己第一个由ChatGPT辅助开发的开源项目goattribute

需求产生 前两天在工作过程中又遇到了一直以来困惑我的一个问题&#xff0c;就是Go配置项的管理问题。 在开发一个新项目的时候&#xff0c;往往涉及到配置项的管理。个人小项目可能会通过配置文件来传入、环境变量来传入&#xff0c;也可能通过命令行参数来传入&#xff0c;公…

代码随想录 LeetCode数组篇 长度最小的子数组

文章目录 &#xff08;中等&#xff09;209. 长度最小的子数组&#xff08;中等&#xff09;904. 水果成篮&#xff08;困难&#xff09;76. 最小夫覆盖子串 &#xff08;中等&#xff09;209. 长度最小的子数组 我的思路&#xff1a;双指针p和q&#xff0c;滑动窗口的思想 每…

牛客练习赛111 D青蛙兔子的约会

题目链接 示例1 输入 3 3 4 10 1 2 2 4 5 1 1 3 5 11 1 1 输出 YES NO NO 说明 第一问&#xff0c;青蛙晚上向右跳1次&#xff0c;白天无法与兔子相遇。青蛙向右跳2次&#xff0c;也就是2a6的距离&#xff0c;白天兔子向左跳1次&#xff0c;可以相遇。所以在跳[1,2]次中&#…

app持续交付实战

app持续交付实战 一、学习目标二、优势三、子任务拆分四、环境依赖1、安卓 SDK2、安卓设备&#xff08;真机 or 模拟器&#xff09;3、Appium 自动化测试4、JDK5、Python3环境6、allure-commandline工具7、allure插件 五、实战任务&#xff1a;串行执行 Jenkins Pipeline 项目1…