【C++】—— 简述C++11新特性

news2024/11/6 3:00:02

序言:

  • 从本期开始,我将会带大家学习的是关于C++11 新增的相关知识!废话不多说,我们直接开始今天的学习。

目录

(一)C++11简介

(二)统一的列表初始化

1、{}初始化

2、std::initializer_list

(三)声明

1、auto

2、decltype

3、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能更好地用于系统开发和库开发、语法更加泛华和简单化、更加稳定和安全,不仅功能更强大,而且能提升程序员的开发效率,公司实际项目开发中也用得比较多,所以我们要作为一个重点去学习。C++11增加的语法特性非常篇幅非常多,我们这里没办法一 一讲解,所以本节课程主要讲解实际中比较实用的语法。

  • 大家在学习过程中也可以参考文档:C++11 - cppreference.com

知识拓展
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++11 的第一个新增特性——有关统一的列表初始化的相关知识!

1、{}初始化

使用大括号 {} 进行初始化可以在不同的情况下提供一致的行为,并且具有一些特殊的初始化规则和语义。

下面是一些 C++11 中使用大括号进行初始化的示例:

  • 直接初始化:
int main()
{
	int x{ 42 }; // 使用大括号直接初始化 x 为 42
	string str{ "Hello" }; // 使用大括号直接初始化字符串对象

	cout << x << endl;
	cout << str << endl;
	return 0;
}

输出展示:

 

  • 默认初始化:
int main()
{
	int x{}; // 使用大括号进行默认初始化,x 的值为 0
	string str{}; // 使用大括号进行默认初始化,str 为空字符串

	cout << x << endl;
	cout << str << endl;
	return 0;
}

输出展示:

  •  数组或结构体初始化

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

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

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

代码展示:

int main()
{
	int x1 = 1;
	int x2{ 2 };

	cout << x1 << endl;
	cout << x2 << endl;
	return 0;
}

输出展示:

 因此,对于上述结构体和数组的初始化操作,在C++11中可以转化为下面这样:

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

	//c++11
	int array1[]{ 1, 2, 3, 4, 5 };
	int array2[5]{ 0 };
	Point p{ 1, 2 };

	return 0;
}

输出展示: 

 

  •  创建对象时也可以使用列表初始化方式调用构造函数初始化
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()
{
	// old style
	Date d1(2022, 1, 1); 
	
	// C++11支持的列表初始化,这里会调用构造函数初始化
	Date d2{ 2022, 1, 2 };
	Date d3 = { 2022, 1, 3 };
	
	return 0;
}

输出展示:

 【解释说明】

  • 这里的本质是构造+拷贝构造,经过优化后。如果不想编译器进行优化设置,可以加上 explicit即可。

 【小结】

  1. 使用大括号初始化在很多情况下都比传统的赋值或括号初始化更加安全和灵活;
  2. 它可以用于解决窄化转换问题,提供统一的初始化语法,并且可以进行更严格的类型检查。

2、std::initializer_list

std::initializer_list 是 C++11 引入的标准库类型,用于方便地表示初始化列表。它是一个轻量级的容器类,用于存储一组相同类型的值。

使用 std::initializer_list 可以将一组值作为参数传递给函数或构造函数,或者用于对象的初始化。它的语法类似于大括号 {} 初始化,但提供了更灵活的传递和使用方式。

下面是一些 std::initializer_list 的常见用法:

  • 作为参数传递给函数
void Point(initializer_list<int> values) {
    for (const auto& value : values) {
        cout << value << " ";
    }
    cout << endl;
}

int main() {
    Point({ 1, 2, 3, 4 }); // 使用初始化列表作为参数
    return 0;
}

输出展示:

 


  • 作为对象的构造函数参数
class MyClass {
public:
    MyClass(initializer_list<int> values) {
        // 在构造函数中使用初始化列表
        for (const auto& value : values) {
            // 处理每个值
            cout << value << " ";
        }
    }
};

int main() 
{
    MyClass obj({ 1, 2, 3, 4 }); // 使用初始化列表作为构造函数参数
    return 0;
}

输出展示:

 


  • 在范围基于循环中使用
int main()
{
	initializer_list<int> values = { 1, 2, 3, 4 };
	for (const auto& value : values) {
		// 处理每个值
		cout << value << " ";
	}
	return 0;
}

输出展示:

 


std::initializer_list 的主要优点是它提供了一种简洁、直观的方式来传递初始化列表,特别适用于带有不确定数量参数的函数或构造函数。它允许以类似于标准容器的方式进行遍历和访问其中的值。

 那是因为在 C++11 中,学从vector 提供了以下构造函数:

 


注意std::initializer_list  是一个只读容器,不能进行元素的插入、删除或修改。它的元素类型是常量,因此通常会使用 const auto& 来遍历元素。

1.插入报错

 

2.删除报错

 

3.修改报错

 

【小结】

  • 总之,std::initializer_list 提供了一种简洁而方便的方式来处理初始化列表,并且在 C++11 及更高版本中广泛使用;
  • 它使我们能够以一种更直观、类型安全的方式处理初始化列表,并简化了函数和构造函数的参数传递。

(三)声明

c++11提供了多种简化声明的方式,尤其是在使用模板时。
 

1、auto

在C++98中auto是一个存储类型的说明符,表明变量是局部自动存储类型,但是局部域中定义局部的变量默认就是自动存储类型,所以auto就没什么价值了。C++11中废弃auto原来的用法,将其用于实现自动类型推断。这样要求必须进行显示初始化,让编译器将定义对象的类型设置为初始化值的类型

下面是一些关于 auto 的使用示例:

  • 自动类型推断
int main()
{
	auto num = 42; // 推断 num 的类型为 int

	auto str = "Hello"; // 推断 str 的类型为 const char*

	auto arr = std::vector<int>(); // 推断 vec 的类型为 std::vector<int>

	return 0;
}

输出展示:

 在这些示例中,auto 关键字根据变量的初始化表达式推断出变量的类型,并相应地声明变量。


  • 与范围基于循环结合使用(这个我们一直都在用就不多说了)

 

  • 函数返回类型推断
auto add(int a, int b) {
    return a + b;
}

在这个示例中,auto 用于推断函数的返回类型。根据返回表达式的类型,编译器会自动推断出函数的返回类型。


【小结】

  1. auto 推断的类型是在编译时确定的,而不是运行时。这意味着使用 auto 声明的变量在编译时会根据初始化表达式的类型进行类型推断,然后在后续的代码中被视为具有确定的类型。
  2. 另外,由于 auto 是根据初始化表达式推断类型,因此在一些情况下可能会导致意外的类型推断结果或不明确的类型。在这些情况下,可以使用显式的类型声明或其他更具体的类型推断工具(例如类型转换操作符)来消除歧义。

2、decltype

关键字decltype将变量的类型声明为表达式指定的类型。

代码举例:

int main()
{
	const int x = 1;
	double y = 2.2;

	decltype(x * y) ret; // ret的类型是double
	decltype(&x) p; // p的类型是 const int*

	cout << typeid(ret).name() << endl;
	cout << typeid(p).name() << endl;


	return 0;
}

输出展示:

 


3、nullptr

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

#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif

(四)范围for循环

这个我们在前面的课程中已经进行了非常详细的讲解,这里就不进行讲解了。


(五)STL中一些变化

新容器
用橘色圈起来是C++11中的一些几个新容器,但是实际最有用的是unordered_map和
unordered_set。这两个我们前面已经进行了非常详细的讲解,其他的大家了解一下即可
 

 


总结

以上便是本期关于 C++11 新特性的介绍。以上内容在校招中属于了解内容,大家知道会用即可!

 

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

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

相关文章

FreeCAD向实体填充\添加材料\镜像\制作投影

任务 在本教程中&#xff0c;您将使用零件设计工作台创建下图所示零件的 3D 实体模型。给出了完成此任务的所有必要维度。 首先从基础草图创建核心形状&#xff0c;然后在该形状的基础上进行构建&#xff0c;添加所谓的特征。 这些特征将使用附加草图和随附的特征操作向实体添…

CTFshow 限时活动 红包挑战9 详细题解

CTFshow红包挑战9 题目源码开源了。源码如下&#xff1a; common.php <?phpclass user{public $id;public $username;private $password;public function __toString(){return $this->username;}}class cookie_helper{private $secret "*************"; /…

搭建电路(最大生成树)

本文为最近做过的一道编程笔试题&#xff0c;代码实现方式多种多样&#xff0c;此处本人提供的代码可以获得正确解&#xff0c;仅供大家参考。 目录 一、题目描述二、实现代码程序三、测试结果截图 一、题目描述 题目描述&#xff1a; 明明迷上了一个搭建电路的游戏。 在游戏…

Prometheus+Grafana+AlertManager监控SpringBoot项目并发送邮件告警通知

文章目录 PrometheusGrafanaAlertManager监控平台搭建新建SpringBoot项目为Prometheus提供指标新建项目&#xff0c;引入依赖新建接口&#xff0c;运行程序 推送指标到pushgateway 开始监控Grafana连接Prometheus数据源导入Grafana模板监控SpringBoot项目 邮件告警通知同系列文…

javaee idea创建maven项目,然后创建servlet

idea创建maven项目 参考我的上一篇博客点击查看 创建servlet 步骤一 引入依赖 步骤二 新建directory并设置mark directory as 步骤三 新建package和servlet

TCP半连接队列和全连接队列

目录 什么是 TCP 半连接队列和全连接队列&#xff1f; TCP 全连接队列溢出 如何知道应用程序的 TCP 全连接队列大小&#xff1f; 如何模拟 TCP 全连接队列溢出的场景&#xff1f; 全连接队列溢出会发生什么 ? 如何增大全连接队列呢 ? TCP 半连接队列溢出 如何查看 TC…

【C#学习笔记】数据类中常用委托及接口——以List<T>为例

文章目录 List\<T\>/LinkedList \<T\>为什么是神&#xff1f;&#xff08;泛型为什么是神&#xff09;一些常见&#xff0c;通用的委托和接口ComparisonEnumerator List<T>/LinkedList <T>为什么是神&#xff1f;&#xff08;泛型为什么是神&#xff0…

STM32 进不了main 函数

1. 我用的是STM32L151C8T6 的芯片&#xff0c;在github 上找了个别人的例程&#xff0c;拿来当模板改&#xff0c;由于他用的是HSE 外部晶振&#xff0c;我用的是内部晶振HSI&#xff0c;所以需要改系统时钟&#xff0c;改完后debug&#xff0c; 一直进不了main 函数&#xff0…

Docker容器与虚拟化技术:GitHub账户注册

目录 一、实验 1.GitHub 一、实验 1.GitHub &#xff08;1&#xff09;GitHub是一个面向开源及私有软件项目的托管平台&#xff0c;因为只支持Git作为唯一的版本库格式进行托管&#xff0c;故名GitHub。 &#xff08;2&#xff09;官网 GitHub: Let’s build from here …

206.Flink(一):flink概述,flink集群搭建,flink中执行任务,单节点、yarn运行模式,三种部署模式的具体实现

一、Flink概述 1.基本描述 Flink官网地址:Apache Flink — Stateful Computations over Data Streams | Apache Flink Flink是一个框架和分布式处理引擎,用于对无界和有界数据流进行有状态计算。 2.有界流和无界流 无界流(流): 有定义流的开始,没有定义结束。会无休止…

Apache StreamPark系列教程第一篇——安装和体验

一、StreamPark介绍 实时即未来,在实时处理流域 Apache Spark 和 Apache Flink 是一个伟大的进步,尤其是Apache Flink被普遍认为是下一代大数据流计算引擎, 我们在使用 Flink & Spark 时发现从编程模型, 启动配置到运维管理都有很多可以抽象共用的地方, 我们将一些好的经验…

机器学习中XGBoost算法调参技巧

本文将详细解释XGBoost中十个最常用超参数的介绍&#xff0c;功能和值范围&#xff0c;及如何使用Optuna进行超参数调优。 对于XGBoost来说&#xff0c;默认的超参数是可以正常运行的&#xff0c;但是如果你想获得最佳的效果&#xff0c;那么就需要自行调整一些超参数来匹配你…

如何深入理解 Node.js 中的流(Streams)

Node.js是一个强大的允许开发人员构建可扩展和高效的应用程序。Node.js的一个关键特性是其内置对流的支持。流是Node.js中的一个基本概念&#xff0c;它能够实现高效的数据处理&#xff0c;特别是在处理大量信息或实时处理数据时。 在本文中&#xff0c;我们将探讨Node.js中的流…

es和数据库同步方案

5.5 课程信息索引同步 5.5.1 技术方案 通过向索引中添加课程信息最终实现了课程的搜索&#xff0c;我们发现课程信息是先保存在关系数据库中&#xff0c;而后再写入索引&#xff0c;这个过程是将关系数据中的数据同步到elasticsearch索引中的过程&#xff0c;可以简单成为索引…

SD-WebUI和ComfyUI的局域网访问设置!

如何通过局域网访问AI绘画软件&#xff0c;这是星球成员提的一个问题&#xff0c;而且两个软件都问到了&#xff0c;我也回答过了。现在把内容整理一下发出来&#xff0c;大家可能用得着。 SD-WebUI和ComfyUI这两个AI绘画工具都是通过浏览器来使用&#xff0c;但是默认情况下并…

oops Framwork creator游戏开发框架

环境&#xff1a; Mac oops Framework 该框架是由gdflas编写&#xff0c;基于cocosCreator 3.x 而实现的开源游戏框架。特点&#xff1a; 框架通过插件方式提供&#xff0c;与项目相分离&#xff0c;方便不同版本平滑升级内置模块低耦合&#xff0c; 可根据需要进行删减&…

如何使用HTML5新增的标签来构建语义化的页面结构?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ <header>&#xff1a;⭐ <nav>&#xff1a;⭐ <main>&#xff1a;⭐ <section>&#xff1a;⭐ <article>&#xff1a;⭐ <aside>&#xff1a;⭐ <footer>&#xff1a;⭐ <figure> 和 &l…

开黑啦kook 机器人开发 PHP swoole Liunx 服务器(宝塔)

安装环境 PHP 拓展 直接使用 宝塔一键安装 &#xff08;Windows系统不支持&#xff09; 设置命令行的PHP版本避免执行脚本时 获取不到 swoole 检查swoole是否安装成功 获取官方SDK GitHub - kaiheila/php-bot: 开黑啦机器人的php版本https://github.com/kaiheila/php-bot 配…

同态排序算法

参考文献&#xff1a; [Batcher68] Batcher K E. Sorting networks and their applications[C]//Proceedings of the April 30–May 2, 1968, spring joint computer conference. 1968: 307-314. [SV11] Smart, N.P., Vercauteren, F.: Fully homomorphic SIMD operations. IA…

智能井盖传感器,物联网智能井盖系统

随着城市人口的不断增加和城市化进程的不断推进&#xff0c;城市基础设施的安全和可靠性变得愈发重要&#xff0c;城市窨井盖作为城市基础设施重要组成部分之一&#xff0c;其安全性事关城市安全有序运行和居民生产生活安全保障。 近年来&#xff0c;各地都在加强城市窨井盖治理…