【C++】C++11——C++11介绍、初始化列表、声明、auto、decltype、nullptr、范围for循环

news2024/11/22 9:03:41

文章目录

  • C++11
    • 1.C++11介绍
    • 2.初始化列表
      • 2.1{}初始化
      • 2.2 std::initializer_list
    • 3.声明
      • 3.1auto
      • 3.2decltype
      • 3.3nullptr
    • 4.范围for循环

C++11

1.C++11介绍

在这里插入图片描述

  C++11是C++编程语言的一个版本,于2011年发布。C++11引入了很多新特性,比如:类型推导(auto关键字)、Lambda表达式、线程库、列表初始化、智能指针、右值引用、包装器等等。 C++11带来了数量可观的变化,其中包含了约140个新特性,以及对C++03标准中约600个缺陷的修正。

  这使得C++11更像是从C++98/03中孕育出的一种新语言。相比较而言,C++11能更好地用于系统开发和库开发、语法更加泛华和简单化、更加稳定和安全,不仅功能更强大,而且能提升程序员的开发效率,公司实际项目开发中也用得比较多。总的来说,C++11使得C++更加现代化、易用和强大。

C++11

             

2.初始化列表

2.1{}初始化

  在C++98中,标准确实允许使用花括号{}对数组或者结构体元素进行统一的列表初始值设定。这种初始化方式被称为“聚合初始化”(Aggregate Initialization)。

  对于数组,可以使用花括号{}将一组值列表初始化为数组的元素。

  对于结构体,如果结构体中的成员都是公有(public)的,并且没有定义构造函数,那么可以使用花括号{}将一组值列表初始化为结构体的成员变量。 例如:

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扩大了初始化列表的使用范围,使其可以用于所有的内置类型和用户自定义的类型。在C++11之前,初始化列表只能用于POD(Plain Old Data)结构体和数组。

  使用初始化列表时,可以选择添加等号(=)或不添加。如果添加等号,则称为“值初始化”,如果不添加等号,则称为“直接初始化”。 这两种方式在C++11中都是有效的。

  值初始化将使用默认值或零值来初始化对象,而直接初始化将使用指定的值来初始化对象。例如:

struct Point
{
	int _x;
	int _y;
};

int main()
{
	int x1 = 1;
	int x2{ 2 };
	int array1[]{ 1, 2, 3, 4, 5 };
	int array2[5]{ 0 };
	Point p{ 1, 2 };
	
	// C++11中列表初始化也可以适用于n ew表达式中
	int* pa = new int[4]{ 0 };
	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()
{
	Date d1(2022, 1, 1); // old style
	
	// C++11支持的列表初始化,这里会调用构造函数初始化
	Date d2{ 2022, 1, 2 };
	Date d3 = { 2022, 1, 3 };
	return 0;
}

            

2.2 std::initializer_list

std::initializer_list介绍

  std::initializer_list是C++11标准库中的一种类型,用于表示某种特定类型的值的数组。它是一种模板类型,定义std::initializer_list对象时,必须说明列表中所含元素的类型。

  std::initializer_list对象可以用于初始化其他对象,或者作为函数的参数进行传递。 和std::vector一样,std::initializer_list也是一种模板类型,但是它和std::vector有一些重要的区别。首先,std::initializer_list对象中的元素永远是常量值,无法改变它们的值。其次,std::initializer_list对象本身并不拥有它所包含的元素,它只是一个指向元素数组的指针,这意味着它不会进行内存分配或释放。

  在使用std::initializer_list时,可以使用花括号{}来创建一个初始化列表,例如:

std::initializer_list<int> ilist = {1, 2, 3, 4, 5};

  在这个例子中,我们创建了一个包含5个整数的std::initializer_list对象。

  

  另外,可以使用begin()和end()成员函数来获取指向初始化列表首元素和尾元素的指针, 例如:

auto begin = ilist.begin();  
auto end = ilist.end();

  这些指针可以用于遍历初始化列表中的元素。需要注意的是,由于std::initializer_list对象中的元素是常量值,因此不能使用指针修改它们的值。

  总的来说,std::initializer_list是一种方便的类型,可以用于初始化其他对象或作为函数参数进行传递。但是需要注意的是,它并不拥有它所包含的元素,而且元素值是常量,无法修改。

            

3.声明

3.1auto

  在C++11中,auto关键字被引入,用于自动类型推导。它允许编译器根据初始化表达式的类型来自动推断变量的类型,而不需要显式地指定变量的类型。

  使用auto关键字可以使代码更加简洁和易读,特别是在处理复杂的类型或模板元编程时。它还可以减少由于手动指定错误类型而引起的错误。

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

#include <iostream>  
#include <vector>  
  
int main() 
{  
    // 自动推导整型变量的类型  
    auto i = 10;  
    std::cout << "i: " << i << std::endl;  
  
    // 自动推导浮点型变量的类型  
    auto f = 3.14;  
    std::cout << "f: " << f << std::endl;  
  
    // 自动推导复杂类型的变量  
    std::vector<int> vec = {1, 2, 3, 4, 5};  
    for (auto element : vec) {  
        std::cout << "element: " << element << std::endl;  
    }  
  
    return 0;  
}

//i: 10  
//f: 3.14  
//element: 1  
//element: 2  
//element: 3  
//element: 4  
//element: 5

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

int main()
{
	int i = 10;
	auto p = &i;
	auto pf = strcpy;
	cout << typeid(p).name() << endl;
	cout << typeid(pf).name() << endl;
	map<string, string> dict = { {"sort", "排序"}, {"insert", "插入"} };
	
	//map<string, string>::iterator it = dict.begin();
	auto it = dict.begin();
	return 0;
}

            

3.2decltype

  在C++11中,decltype关键字被引入,用于在编译时推断表达式的类型。它允许编译器根据表达式的类型来推断变量的类型,而不需要显式地指定变量的类型。

  decltype的使用方式如下:

decltype(expression) variable_name;

  其中,expression是一个表达式,可以是变量、函数调用、算术运算等等。decltype会根据expression的类型来推断variable_name的类型。
  

  下面是一些使用decltype的示例:

#include <iostream>  
#include <vector>  
  
int main() {  
    int i = 10;  
  
    // decltype推导整型变量的类型  
    decltype(i) j = 20;  
    std::cout << "j: " << j << std::endl;  
  
    // decltype推导复杂类型的变量  
    std::vector<int> vec = {1, 2, 3, 4, 5};  
    for (decltype(vec)::size_type index = 0; index != vec.size(); ++index) 
    {  
        std::cout << "vec[" << index << "]: " << vec[index] << std::endl;  
    }  
  
    return 0;  
}

//j: 20  
//vec[0]: 1  
//vec[1]: 2  
//vec[2]: 3  
//vec[3]: 4  
//vec[4]: 5

  在上面的示例中,decltype关键字被用于推断变量j和index的类型。编译器根据表达式的类型自动确定变量的类型,从而使代码更加简洁和易读。 需要注意的是,在推导复杂类型时,可以使用decltype和作用域解析运算符::来指定类型的嵌套部分。

// decltype的一些使用使用场景
template<class T1, class T2>
void F(T1 t1, T2 t2)
{
	decltype(t1 * t2) ret;
	cout << typeid(ret).name() << endl;
}

int main()
{
	const int x = 1;
	double y = 2.2;
	decltype(x * y) ret; // ret的类型是double
	decltype(&x) p;      // p的类型是int*
	
	cout << typeid(ret).name() << endl;
	cout << typeid(p).name() << endl;
	F(1, 'a');
	return 0;
}

            

3.3nullptr

  在C++11之前,C++使用NULL宏来表示指针的“空”值。然而,NULL宏在某些情况下可能会导致歧义,因为它在不同的上下文中可能有不同的含义。为了解决这个问题,C++11引入了nullptr关键字,用于表示指针的“空”值。

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

  nullptr是一种特殊类型的字面量,它可以被转换为任何其他指针类型,也可以被转换为bool类型(在这种情况下,它的值为false)。与NULL不同的是,nullptr是一种类型安全的指针空值,它不会引发整数溢出或其他与整数相关的问题。

  下面是使用nullptr的示例:

  ptr1被初始化为nullptr,而ptr2被初始化为0。然后,通过检查指针是否为nullptr来判断指针是否为空。使用nullptr可以使代码更加清晰和易于理解,因为它明确表示指针的值为“空”。

#include <iostream>  
  
int main() {  
    int* ptr1 = nullptr; // 使用nullptr初始化指针  
    int* ptr2 = 0; // 使用0初始化指针(不推荐)  
  
    if (ptr1) {  
        std::cout << "ptr1 is not null" << std::endl;  
    } else {  
        std::cout << "ptr1 is null" << std::endl;  
    }  
  
    if (ptr2) {  
        std::cout << "ptr2 is not null" << std::endl;  
    } else {  
        std::cout << "ptr2 is null" << std::endl;  
    }  
  
    return 0;  
}

//ptr1 is null  
//ptr2 is null

            

4.范围for循环

  在C++11中,可以使用范围for循环来遍历容器中的元素。 范围for循环的语法如下:

for (decltype(container)::value_type element : container) 
{  
    // 循环体  
}

  其中,container是一个容器对象,如std::vector、std::list等。decltype(container)::value_type表示容器中元素的类型。

  范围for循环会依次遍历容器中的每个元素,并将当前元素的值赋给循环变量element。在循环体内,可以使用element来访问当前元素的值。

  

  下面是一个使用范围for循环遍历std::vector并返回每个元素值的示例:

  getVector()函数返回一个std::vector对象。在main()函数中,使用范围for循环遍历该对象,并在循环体内返回当前元素的值。

#include <iostream>  
#include <vector>  
  
std::vector<int> getVector() {  
    std::vector<int> vec = {1, 2, 3, 4, 5};  
    return vec;  
}  
  
int main() {  
    std::vector<int> vec = getVector();  
    for (int element : vec) {  
        std::cout << "element: " << element << std::endl;   
    }  
    return 0;  
}

//element: 1  
//element: 2  
//element: 3  
//element: 4  
//element: 5

            

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

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

相关文章

多线程 - 单例模式

单例模式 ~~ 单例模式是常见的设计模式之一 什么是设计模式 你知道象棋,五子棋,围棋吗?如果,你想下好围棋,你就不得不了解一个东西,”棋谱”,设计模式好比围棋中的 “棋谱”. 在棋谱里面,大佬们,把一些常见的对局场景,都给推演出来了,照着棋谱来下棋,基本上棋力就不会差到哪…

思科:iOS和iOSXe软件存在漏洞

思科警告说,有人试图利用iOS软件和iOSXe软件中的一个安全缺陷,这些缺陷可能会让一个经过认证的远程攻击者在受影响的系统上实现远程代码执行。 中严重程度的脆弱性被追踪为 CVE-2023-20109 ,并以6.6分得分。它会影响启用Gdoi或G-Ikev2协议的软件的所有版本。 国际知名白帽黑客…

CSS鼠标指针表

(机翻)搬运自:cursor - CSS: Cascading Style Sheets | MDN (mozilla.org) 类型Keyword演示注释全局autoUA将基于当前上下文来确定要显示的光标。例如&#xff0c;相当于悬停文本时的文本。default 依赖于平台的默认光标。通常是箭头。none不会渲染光标。链接&状态contex…

最短路径专题2 Dijkstra 最短距离(堆优化版)

题目&#xff1a;样例&#xff1a; 输入 6 6 0 0 1 2 0 2 5 0 3 1 2 3 2 1 2 1 4 5 1 输出 0 2 3 1 -1 -1 思路&#xff1a; 根据题意&#xff0c;数据范围也小&#xff0c;也可以用朴素版的Dijsktra来做&#xff0c;朴素版的Dijsktra我做过了一遍了&#xff0c;可以看以一下我…

【统计学】Top-down自上而下的角度模型召回率recall,精确率precision,特异性specificity,模型评价

最近在学 logistic regression model&#xff0c;又遇见了几个之前的老面孔。 召回率recall, 精确率precision&#xff0c;特异性spcificity&#xff0c;准确率accuracy&#xff0c;True positive rate&#xff0c;false positive rate等等名词在学习之初遇到的困难在于&#x…

Vue3最佳实践 第六章 Pinia,Vuex与axios,VueUse 2(Vuex)

Vuex 状态管理 Vuex 是一种集中管理所有组件中数据的机制。它和Pinia一样都是解决使用 props 和 $emit 事件在组件之间传递数据时&#xff0c;当组件之间频繁传递&#xff0c;层级增加时管理数据就变得困难。Vue 的官方状态管理库已更改为Pinia&#xff0c;Pinia 具有与 Vue 几…

微信小程序-1

微信开发文档 https://developers.weixin.qq.com/miniprogram/dev/framework/ 报错在调试器的console里找 一、结构 Ctrl 放大字体 Ctrl - 缩小 设置 - - - 外观设置 - - - 可以修改喜欢的主题颜色 index.js index.json index.wxml 》 html <view class"box&qu…

【kubernetes】kubernetes中的StatefulSet使用

TOC 1 为什么需要StatefulSet 常规的应用通常使用Deployment&#xff0c;如果需要在所有机器上部署则使用DaemonSet&#xff0c;但是有这样一类应用&#xff0c;它们在运行时需要存储一些数据&#xff0c;并且当Pod在其它节点上重建时也希望这些数据能够在重建后的Pod上获取&…

Python爬虫案例入门教程(纯小白向)——夜读书屋小说

Python爬虫案例——夜读书屋小说 前言 如果你是python小白并且对爬虫有着浓厚的兴趣&#xff0c;但是面对网上错综复杂的实战案例看也看不懂&#xff0c;那么你可以尝试阅读我的文章&#xff0c;我也是从零基础python开始学习爬虫&#xff0c;非常清楚在过程中所遇到的困难&am…

字符编码的了解

前言&#xff1a; 在编写文件读取功能的过程中&#xff0c;我遭遇了一个棘手的乱码难题。经过细致的排查&#xff0c;发现这一问题的根源在于文件的字符编码。为了帮助大家有效地克服编码差异所带来的开发挑战&#xff0c;因此&#xff0c;我收集了字符集编码的相关知识&#x…

想要精通算法和SQL的成长之路 - 旋转链表

想要精通算法和SQL的成长之路 - 旋转链表 前言一. 旋转链表 前言 想要精通算法和SQL的成长之路 - 系列导航 一. 旋转链表 原题链接 由于k的大小可能超过链表长度&#xff0c;因此我们需要根据链表长度取模。那么我们首先需要去计算链表的长度是多少&#xff1a; if (head …

C# GraphicsPath 类学习

先在窗体放2个picturebox&#xff0c; 然后看一下如下代码&#xff1b; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; us…

Pytorch基础:Tensor的transpose方法

相关阅读 Pytorch基础https://blog.csdn.net/weixin_45791458/category_12457644.html?spm1001.2014.3001.5482 在Pytorch中&#xff0c;transpose是Tensor的一个重要方法&#xff0c;同时它也是一个torch模块中的一个函数&#xff0c;它们的语法如下所示。 Tensor.transpo…

window安装压缩版postgresql

环境&#xff1a; window 11 专业版postgresql-16.0-1-windows-x64-binaries.zip 一、下载 1.1 从官网下载 https://www.postgresql.org/download/windows/ 1.2 从百度网盘下载 链接&#xff1a;https://pan.baidu.com/s/1fmQbgWSzX4hN07Lgdzfz0g?pwddzyy 提取码&#…

汇编语言王爽第4版实验8答案(和你想的不一样)

实验8 分析一个奇怪的程序 E:\mywork\asm\p906.asm C:\>edit p906.asm assume cs:codecode segmentmov ax,4c00hint 21h start: mov ax,0 s:nop ; nop的机器码占一个字节nopmov di, offset smov si, offset s2mov ax, cs:[si]mov cs:[di],ax s0:jmp short s s1:mov ax,0in…

tauri为窗口添加阴影效果

需求 为窗口添加阴影效果&#xff0c;让窗口显得更立体。 实现方案 通过 tauri 中的 window-shadows 依赖实现。 编码 修改 label 标签内容 修改 src-tauri/tauri.conf.json 文件&#xff0c;设置 label 字段为 “customization” 增加shadows的依赖 修改 src-tauri…

第8期ThreadX视频教程:应用实战,将裸机工程移植到RTOS的任务划分,驱动和应用层交互,中断DMA,C库和中间件处理等注意事项

视频教程汇总帖&#xff1a;【学以致用&#xff0c;授人以渔】2023视频教程汇总&#xff0c;DSP第12期&#xff0c;ThreadX第8期&#xff0c;BSP驱动第26期&#xff0c;USB实战第5期&#xff0c;GUI实战第3期&#xff08;2023-10-01&#xff09; - STM32F429 - 硬汉嵌入式论坛 …

函数、函数的傅里叶级数展开、傅里叶级数的和函数之间的关系

1.函数、函数的傅里叶级数展开、傅里叶级数的和函数之间的关系 1.1 傅里叶级数中的系数公式推导 我们先来推导一下傅里叶级数中的系数公式&#xff0c;其实笔者已经写过一篇相关笔记&#xff0c;详见&#xff1a;为什么要把一个函数分解成三角函数?(傅利叶级数) f ( x )…

MySQL 索引优化实践(单表)

目录 一、前言二、表数据准备三、常见业务无索引查询耗时测试3.1、通过订单ID / 订单编号 查询指定订单3.2、查询订单列表 四、订单常见业务索引优化实践4.1、通过唯一索引和普通索引优化通过订单编号查询订单信息4.2、通过普通联合索引优化订单列表查询4.2.1、分析查询字段的查…

【数据结构】HashSet的底层数据结构

&#x1f40c;个人主页&#xff1a; &#x1f40c; 叶落闲庭 &#x1f4a8;我的专栏&#xff1a;&#x1f4a8; c语言 数据结构 javaEE 操作系统 Redis 石可破也&#xff0c;而不可夺坚&#xff1b;丹可磨也&#xff0c;而不可夺赤。 HashSet 一、 HashSet 集合的底层数据结构二…