• C++11初篇(快速了解)


    1. 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增加的语法特性非常篇幅非常多,我们这里没办法一 一讲解,所以本节课程主要讲解实际中比较实用的语法。

    2. 统一的列表初始化

    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;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 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中列表初始化也可以适用于new表达式中
    	int* pa = new int[4]{ 0 };
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 创建对象时也可以使用列表初始化方式调用构造函数初始化
    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    2.2 std::initializer_list

    链接:std::initializer_list的介绍文档:

    • std::initializer_list是什么类型:
      在这里插入图片描述
    • std::initializer_list使用场景:

    std::initializer_list一般是作为构造函数的参数,C++11对STL中的不少容器就增加 std::initializer_list作为参数的构造函数,这样初始化容器对象就更方便了。也可以作为operator=的参数,这样就可以用大括号赋值。

    int main()
    {
    	vector<int> v = { 1,2,3,4 };
    	list<int> lt = { 1,2 };
    	// 这里{"sort", "排序"}会先初始化构造一个pair对象
    	map<string, string> dict = { {"sort", "排序"}, {"insert", "插入"} };
    	// 使用大括号对容器赋值
    	v = { 10, 20, 30 };
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 让模拟实现的vector也支持{}初始化和赋值
    namespace Ding
    {
    	template<class T>
    	class vector {
    	public:
    		typedef T* iterator;
    		vector(initializer_list<T> l)
    		{
    			_start = new T[l.size()];
    			_finish = _start + l.size();
    			_endofstorage = _start + l.size();
    			iterator vit = _start;
    			typename initializer_list<T>::iterator lit = l.begin();
    			while (lit != l.end())
    			{
    				*vit++ = *lit++;
    			}
    			//for (auto e : l)
    			// *vit++ = e;
    		}
    		vector<T>& operator=(initializer_list<T> l) {
    			vector<T> tmp(l);
    			std::swap(_start, tmp._start);
    			std::swap(_finish, tmp._finish);
    			std::swap(_endofstorage, tmp._endofstorage);
    			return *this;
    		}
    	private:
    		iterator _start;
    		iterator _finish;
    		iterator _endofstorage;
    	};
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    3. 声明

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

    3.1 auto

    • 在C++98中auto是一个存储类型的说明符,表明变量是局部自动存储类型,但是局部域中定义局部的变量默认就是自动存储类型,所以auto就没什么价值了。
    • C++11中废弃auto原来的用法,将其用于实现自动类型腿断。这样要求必须进行显示初始化,让编译器将定义对象的类型设置为初始化值的类型。
    int main()
    {
    	int i = 10;
    	auto p = &i;
    	cout << typeid(p).name() << endl;
    	map<string, string> dict = { {"sort", "排序"}, {"insert", "插入"} };
    	//map::iterator it = dict.begin();
    	auto it = dict.begin();
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    3.2 decltype

    • 关键字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的类型是const int*
    	cout << typeid(ret).name() << endl;
    	cout << typeid(p).name() << endl;
    	F(1, 'a');
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在这里插入图片描述

    3.3 nullptr

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

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

    4 范围for循环

    • 其实范围for的底层就是迭代器的实现。
      在这里插入图片描述
  • 相关阅读:
    HTML(超文本标记语言)
    CUDA优化之LayerNorm性能优化实践
    网络——路由器
    Open3D(C++)点云处理算法汇总(C++长期更新版)
    2022-09-09 Unity InputSystem4——输入配置文件
    LC滤波器设计学习笔记(一)滤波电路入门
    TPH-YOLOv5: 基于Transformer预测头的改进YOLOv5用于无人机捕获场景目标检测
    ROS数据格式转换:LaserScan转MultiEchoLaserScan
    webpack自定义plugin
    HR 必知的 360 度评估的优缺点
  • 原文地址:https://blog.csdn.net/Dingyuan0/article/details/127890538