C++【C++11】
创始人
2024-01-27 03:30:28
0

文章目录

  • 一、统一的列表初始化
    • 1.用{}来初始化元素
    • 2.initializer_list
  • 二、自动类型推断
    • 3.auto
    • 4.decltype
  • 三、指针
    • 5.nullptr
    • 6.范围for
  • 四、STL中的一些新变化
    • 1.新增加的容器
    • 2.容器内部的变化

一、统一的列表初始化

1.用{}来初始化元素

在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中,我们都可以使用{}来对我们的元素进行初始化
C++11扩大了用大括号括起的列表(初始化列表)的使用范围,使其可用于所有的内置类型和用户自定义的类型,使用初始化列表时,可添加等号(=),也可不添加

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;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()
{int x1 = 1;// 要能看懂,但是不建议使用int x2 = { 2 };int x3 { 2 };// 都是在调用构造函数Date d1(2022, 11, 22);// C++11 要能看懂,但是不建议使用Date d2 = {2022, 11, 11}; // ->调用构造函数Date d3{ 2022, 11, 11 };return 0;
}

在这里插入图片描述

2.initializer_list

C++11中有了一种新的类型,initializer_list,语法上原生支持通过大括号的方式初始化给它。它就像一个顺序表一样,支持迭代器,但是不支持插入数据。
在这里插入图片描述

int main()
{// 调用支持list (initializer_list il)类似这样的构造函数vector v1 = { 1, 2, 3, 4, 5, 6 };vector v2 { 1, 2, 3, 4, 5, 6 };list lt1 = { 1, 2, 3, 4, 5, 6 };list lt2{ 1, 2, 3, 4, 5, 6 };//c++11这里新增了一个类型initializer_list类型来实现,是这里默认需要的一个容器auto x = { 1, 2, 3, 4, 5, 6 };cout << typeid(x).name() << endl;return 0;
}

在这里插入图片描述
那我们的vector等容器又是如何支持大括号的初始化的呢?
因为我们的C++11同时也对我们的库函数进行了更新,让我们的库函数都支持通过initializer_list来进行构造。
这里我们查看一下vector的构造函数中多了一个构造方法,也就是我们的initializer
在这里插入图片描述
在这里插入图片描述
那如何让我们自己之前写过的vector支持通过initializer来初始化

vector(initializer_list il):_start(nullptr),_finish(nullptr),_end_of_storage(nullptr){reserve(il.size());iterator it=begin();for(auto&e:il){push_back(e);}}

测试代码

void myvector_test18(){vector v1={1,2,3,4,5,6,7,8,9,10};vector v2{1,2,3,4,5,6,7,8,9,10};for(auto e:v2){cout<

在这里插入图片描述

当然,我们的map,set,pair等容器也可以通过这种方式进行构造

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;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, 11, 22);Date d2 = {2022, 11, 11}; Date d3{ 2022, 11, 11 };vector v3 = {d1, d2, d3};vector v4 = { { 2022, 1, 1 }, {2022, 11, 11} };string s1 = "11111";// 构造//这相当于就是隐式类型转换//构造一个pair我们也可以通过{}的方式构造map dict = { { "sort", "排序" }, { "insert", "插入" } };return 0;
}

在这里插入图片描述
当然在我们的C++11的库中,还将许多赋值也进行了重载,让其能够支持initializer进行赋值
在这里插入图片描述
下面是我们的测试代码

#include 
#include 
using namespace std;int main()
{// 构造//这相当于就是隐式类型转换//构造一个pair我们也可以通过{}的方式构造map dict = { { "sort", "排序" }, { "insert", "插入" } };// 赋值重载//这里不写auto让编译器自动去推断,我们的编译器是没有办法匹配出来的。initializer_list> kvil = { { "left", "左边" }, { "left", "左边" } };dict = kvil;return 0;
}

总结:
C++11之后,一切对象都可以用列表初始化。但是我们建议普通对象还是用以前的方式初始化,容器可以采用花括号进行初始化。

二、自动类型推断

3.auto

在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 dict = { {"sort", "排序"}, {"insert", "插入"} };//如果我们这里要自己写的话,需要写一长串,但是使用auto的话就非常方便//map::iterator it = dict.begin();auto it = dict.begin();return 0;
}

如果我们这里使用auto的话,我们上面代码中的迭代器的类型等等,我们都不用自己手写,就非常方便,但是我们如果使用了auto进行自动类型推断,我们代码的可读性就会变差,但是有些编译器会给你标识出来(比方说clion)。
在这里插入图片描述

4.decltype

typename可以推导对象的类型,但是我们不能通过这个推导出来的类型来定义我们的对象,只是单纯地拿到这个类型的字符串。
但是如果我们想要用推导出来的类型重新定义一个新的对象呢?

int main()
{int x = 10;// typeid拿到只是类型的字符串,不能用这个再去定义对象什么的// 下面这样写会报错的,没有下面这样的用法//	typeid(x).name() y = 20;decltype(x) y1 = 20.22;//auto和decltype是不一样的,我们的auto这里推导出来的是double,也就是我们右边的赋值的元素的类型是什么,我们auto推导出来也就是什么//但是我们的deltype推导出来的类型是x的类型,也就是intauto y2 = 20.22;cout << y1 << endl;cout << y2 << endl;return 0;
}

在这里插入图片描述

三、指针

5.nullptr

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

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

6.范围for

这里的范围for和我们java中的增强for有些相似,底层是一个迭代器。
可以查看我们之前的博客中的迭代器和范围for相关的部分

int main()
{vector tmp{1,2,3,4,5,6,7,8,9};for(auto i:tmp){cout<

在这里插入图片描述

四、STL中的一些新变化

1.新增加的容器

在这里插入图片描述
< array >和< forward_list >显得有些鸡肋
因为< array >是固定大小的数组容器,不支持尾插和尾删,支持[]迭代器。
C++11增加这个的初衷是为了替代c语言中的数组

int main()
{const size_t N = 100;int a1[N];// C语言数组越界检查,越界读基本检查不出来,越界写是抽查a1[N];//a1[N] = 1;a1[N+5] = 1;// 越界读写都可以被检查出来// 实际情况:array用得很少,一方面大家用c数组用惯了// 用array不如用vector + resize去替代c数组array a2;a2[N];a2[N] = 1;a2[N + 5] = 1;return 0;
}

< forward_list >是一个单链表,我们的< list >是双向链表,在使用的时候其实< forward_list >插入的是在我们当前指定位置的后一个位置插入,然后erase并不是擦除当前的位置,而是擦除当前位置的下一个位置

2.容器内部的变化

1.都支持了initializer_list构造,用来支持列表初始化
2.比较鸡肋的接口,比如cbegin,cend系列
3.移动构造和移动赋值,用来对标拷贝构造和拷贝赋值,在某些场景下可以提高效率
(set&&x);
(set& operator=(set&&x)
4.右值引用的参数的插入
在这里插入图片描述

相关内容

热门资讯

农村六个创业项目 最适合农村的... 洗一套衣服只需2元左右的成本,收费10元,翻新、清洗一件皮衣成本1-2元,收50-80元,日收活在5...
亳州炒货机小本创业首选项目 亳... 炒货机亳州炒货机,宿州炒货机小本创业首选项目致诚机械板栗机厂专业生产、批发、供应、销售各款炒板栗机器...
市场空亳州炒货机小本创业首选项... 创业俨然成为了当今社会致富的主要途径,而创业的风险又是让很多投资者忌惮。为了降低风险又不至于错过这个...
成都女人做什么创业项目比较好推... 成都女人做什么创业项目比较好推荐对于一个普通创业者来说,在选择项目的时候,一定要考虑自己的兴趣所在。...
创业小本项目有哪些 创业小本项... 2019小本创业项目有哪些呢?创业首先就是要确定一个好的创业项目,有了好的创业项目创业就会事半功倍,...
适合小本创业的项目有哪些?推荐... 最近个人定制产品很火热,个性化私人订制产品是一个非常好的创业项目,是一个适合想要自己创业做小生意的挣...
现在什么项目好做 【行业吧】 ... 80后创业怎么能大钱,80后自主创业成为很多想要创业的人的疑问,下面渠道小编辑现在什么项目好做?16...
适合小本创业的项目有哪些 适合... 可以开一个小吃店,随着旅游业的发展,各地有名的小吃也得到了许多人的喜爱。做小吃,一定要有特色。。。你...
小本创业涨收入好项目 小本创业... 小本投资项目都有哪些,小本投资项目大全,想知道有哪些小本涨收入投资项目吗,想知道这些小本投资涨收入项...
这8个高收入小本创业项目 你绝... 劣势:这种小规模家庭型的宠物配种业,由于场地,规模,客源,配种周期等因素,年投资回报不是太高。结论:...