当前位置:   article > 正文

【C++航海王:追寻罗杰的编程之路】C++11(一)

【C++航海王:追寻罗杰的编程之路】C++11(一)

目录

1 -> C++11简介

2 -> 统一的列表初始化

2.1 -> {}初始化

2.2 -> std::initializer_list

3 -> 声明

3.1 -> auto

3.2 -> decltype

3.3 -> nullptr


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能更好地用于系统开发和库开发、语法更加泛华和简单化、更加稳定和安全,不仅功能更
强大,而且能提升程序员的开发效率,公司实际项目开发中也用得比较多。

2 -> 统一的列表初始化

2.1 -> {}初始化

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

  1. #define _CRT_SECURE_NO_WARNINGS 1
  2. #include <iostream>
  3. using namespace std;
  4. struct fyd
  5. {
  6. int x;
  7. int y;
  8. };
  9. int main()
  10. {
  11. int array1[] = { 1, 2, 3, 4, 5 };
  12. int array2[5] = { 0 };
  13. fyd p = { 1, 2 };
  14. return 0;
  15. }

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

  1. #define _CRT_SECURE_NO_WARNINGS 1
  2. #include <iostream>
  3. using namespace std;
  4. struct fyd
  5. {
  6. int x;
  7. int y;
  8. };
  9. int main()
  10. {
  11. int x1 = 1;
  12. int x2{ 2 };
  13. int array1[]{ 1, 2, 3, 4, 5 };
  14. int array2[5]{ 0 };
  15. fyd p{ 1, 2 };
  16. // C++11中列表初始化也可以适用于new表达式中
  17. int* pa = new int[4]{ 0 };
  18. return 0;
  19. }

创建对象时也可以使用列表初始化方式调用构造函数初始化

  1. #define _CRT_SECURE_NO_WARNINGS 1
  2. #include <iostream>
  3. using namespace std;
  4. class Date
  5. {
  6. public:
  7. Date(int year, int month, int day)
  8. :_year(year)
  9. , _month(month)
  10. , _day(day)
  11. {
  12. cout << "Date(int year, int month, int day)" << endl;
  13. }
  14. private:
  15. int _year;
  16. int _month;
  17. int _day;
  18. };
  19. int main()
  20. {
  21. Date d1(2024, 4, 1);
  22. // C++11支持的列表初始化,这里会调用构造函数初始化
  23. Date d2{ 2024, 4, 2 };
  24. Date d3 = { 2024, 4, 3 };
  25. return 0;
  26. }

2.2 -> std::initializer_list

std::initializer_list的介绍文档

std::initializer_list是什么类型:

  1. #define _CRT_SECURE_NO_WARNINGS 1
  2. #include <iostream>
  3. using namespace std;
  4. int main()
  5. {
  6. auto il = { 10, 20, 30 };
  7. cout << typeid(il).name() << endl;
  8. return 0;
  9. }

std::initializer_list使用场景:

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

list

vector

map

operator=

  1. #define _CRT_SECURE_NO_WARNINGS 1
  2. #include <iostream>
  3. #include <vector>
  4. #include <map>
  5. #include <list>
  6. using namespace std;
  7. int main()
  8. {
  9. vector<int> v = { 1,2,3,4 };
  10. list<int> lt = { 1,2 };
  11. // 这里{"sort", "排序"}会先初始化构造一个pair对象
  12. map<string, string> dict = { {"sort", "排序"}, {"insert", "插入"} };
  13. // 使用大括号对容器赋值
  14. v = { 10, 20, 30 };
  15. return 0;
  16. }

让模拟实现的vector也支持{}初始化和赋值

  1. #define _CRT_SECURE_NO_WARNINGS 1
  2. #include <iostream>
  3. #include <vector>
  4. #include <map>
  5. #include <list>
  6. using namespace std;
  7. namespace fyd
  8. {
  9. template<class T>
  10. class vector
  11. {
  12. public:
  13. typedef T* iterator;
  14. vector(initializer_list<T> l)
  15. {
  16. _start = new T[l.size()];
  17. _finish = _start + l.size();
  18. _endofstorage = _start + l.size();
  19. iterator vit = _start;
  20. typename initializer_list<T>::iterator lit = l.begin();
  21. while (lit != l.end())
  22. {
  23. *vit++ = *lit++;
  24. }
  25. //for (auto e : l)
  26. //   *vit++ = e;
  27. }
  28. vector<T>& operator=(initializer_list<T> l)
  29. {
  30. vector<T> tmp(l);
  31. std::swap(_start, tmp._start);
  32. std::swap(_finish, tmp._finish);
  33. std::swap(_endofstorage, tmp._endofstorage);
  34. return *this;
  35. }
  36. private:
  37. iterator _start;
  38. iterator _finish;
  39. iterator _endofstorage;
  40. };
  41. }

3 -> 声明

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

3.1 -> auto

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

  1. #define _CRT_SECURE_NO_WARNINGS 1
  2. #include <iostream>
  3. #include <vector>
  4. #include <map>
  5. #include <list>
  6. using namespace std;
  7. int main()
  8. {
  9. int i = 10;
  10. auto p = &i;
  11. auto pf = strcpy;
  12. cout << typeid(p).name() << endl;
  13. cout << typeid(pf).name() << endl;
  14. map<string, string> dict = { {"sort", "排序"}, {"insert", "插入"} };
  15. //map<string, string>::iterator it = dict.begin();
  16. auto it = dict.begin();
  17. return 0;
  18. }

3.2 -> decltype

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

  1. #define _CRT_SECURE_NO_WARNINGS 1
  2. #include <iostream>
  3. #include <vector>
  4. #include <map>
  5. #include <list>
  6. using namespace std;
  7. // decltype的一些使用使用场景
  8. template<class T1, class T2>
  9. void F(T1 t1, T2 t2)
  10. {
  11. decltype(t1 * t2) ret;
  12. cout << typeid(ret).name() << endl;
  13. }
  14. int main()
  15. {
  16. const int x = 1;
  17. double y = 2.2;
  18. decltype(x * y) ret; // ret的类型是double
  19. decltype(&x) p; // p的类型是int*
  20. cout << typeid(ret).name() << endl;
  21. cout << typeid(p).name() << endl;
  22. F(1, 'a');
  23. return 0;
  24. }

3.3 -> nullptr

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

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

感谢大佬们支持!!!

互三啦!!!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/一键难忘520/article/detail/922661
推荐阅读
相关标签
  

闽ICP备14008679号