• C++11(一)新的标准


    一、统一的列表初始化

    1.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扩大了用大括号括起的列表(初始化列表)的使用范围,使其可用于所有的内置类型和用户自定义的类型,使用初始化列表时,可添加等号(=),也可不添加。

    struct Point
    {
    	int _x;
    	int _y;
    	Point(int x, int y) 
    		:_x(x)
    		,_y(y)
    	{
    		cout << "Point(int x, int y)" << endl;
    	}
    };
    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中列表初始化也可以适用于new表达式中
    	int* pa = new int[4]{ 1,2,3,4 };
    	Point* ptr = new Point[2]{ {2,2},{3,3} };
    	return 0;
    }
    

    1.2 explicit关键字

    防止隐式类型转换
    我们之前学习类和对象时知道,单参的构造函数具有隐式类型转换的作用,但是我们有些时候,不想让他进行隐式类型转化。

    // 单参数
    class A
    {
    private:
    	int _a;
    public:
    	explicit A(int a)
    		:_a(a)
    	{}
    };
    int main()
    {
    	A a1(1);
    	A a2 = { 2 };// 这里就是 2转换成一个int对象,再拷贝构造给a2对象
    	return 0;	
    }
    

    1.3 std::initializer_list

    int main()
    {
    	// C++98
    	vector<int> v1;
    	v1.push_back(1);
    	v1.push_back(2);
    	v1.push_back(3);
    
    	// C++11
    	vector<int> v2 = { 1,2,3,4,5,6,7 };
    
    	initializer_list<int> il = { 1,2,3,4,5,6,7 };
    
    	return 0;
    }
    

    支持的原理:新增了一个构造函数(list,map,set等等都新增了这个构造函数,原理也是一样的)
    在这里插入图片描述

    initializer_list在C++里面是一个容器,把一个花括号及其里面的内容(看做一个整体)传给il对象,这个il对象的类型就是initializer_list

    在这里插入图片描述
    模拟实现:

    vector(initializer_list<T> ilt)
    {
    	typename initializer_list<T>::iterator it = ilt.begin();
    	while (it!=ilt.end())
    	{
    		ilt.push_back(*it);
    		++it;
    	}
    }
    

    二、声明

    2.1 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<string, string> dict = { {"sort", "排序"}, {"insert", "插入"} };
    	//map::iterator it = dict.begin();
    	auto it = dict.begin();
    
    	return 0;
    }
    

    2.2 decltype

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

    int main()
    {
    	const int x = 1;
    	double y = 2.2;
    
    	
    	decltype(x) z = 1;	// 拿x的类型来定义新的变量
    	decltype(x * y) ret;// ret的类型是double
    	decltype(&x) p;		// p的类型是int*
    	return 0;
    }
    '
    运行

    实用场景:
    在定义模板的时候特别有用,因为只有等到模板被实例化时才能确定类型

    int func(int a)
    {
    	cout << "int func(int a)" << endl;
    	return a;
    }
    int main()
    {
    	int(*pfunc1)(int) = func;  //函数指针
    	auto pfunc2 = func;
    	decltype(&func) pfunc3;
    	
    	// 只能用decltype的场景——模板
    	vector<decltype(func)> v;
    	//vector v;报错
    	return 0;
    }
    

    2.3 nullptr

    空指针是不会指向有效数据的指针。以前C++在源代码中使用0表示这种指针,但是内部表示可能不同。这带来了一些问题,因为这使得0既可以表示指针常量,又可以表示整型常量。所以出于清晰和安全的角度考虑,C++11中新增了nullptr,用于表示空指针。

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

    三、STL中的一些变化

    3.1 新增容器

    这几个新增容器中,实际最有用的是unordered_mapunordered_set
    在这里插入图片描述
    vector与array的区别
    array的价值:
    1、支持迭代器,更好兼容STL
    2、对于越界的检查

    int a[10];
    	a[14] = 0;		//抽查 *(a+14)=0;
    	array[14] = 0;	//必查 array.operator[](14)=0;
    					//调用assert,断言检查
    

    3.2 新增一些好用高效的接口

    比如:初始化列表、右值引用版本的接口函数、移动构造、移动赋值
    在这里插入图片描述

  • 相关阅读:
    基于内存的分布式NoSQL数据库Redis(一)介绍与安装
    LeetCode 953. Verifying an Alien Dictionary
    (几何) 凸包问题
    微信小程序项目实例SSM项目校园活动报名网
    交易日均千万订单的存储架构设计与实践 | 京东物流技术团队
    适配器模式适配出栈和队列及优先级队列
    MQTT X Web:在线的 MQTT 5.0 客户端工具
    区块链的四大特征
    kotlin协程与线程池
    滴滴-小桔充电
  • 原文地址:https://blog.csdn.net/weixin_57675461/article/details/127041926