• C++查漏补缺与新标准(C++20,C++17,C++11)02 C++快速回顾(二)


    本内容参考C++20高级编程

    C风格的数组

    1. //形如
    2. int myArray[3]{2};

    一个比较新颖的获取C风格数组大小的函数std::size(),返回size_t类型(在中定义的无符号整数)

    1. #include <iostream>
    2. using namespace std;
    3. int main()
    4. {
    5. int myArray[5] = { 0 };
    6. size_t arraySize{size(myArray)};
    7. cout << arraySize;
    8. return 0;
    9. }

    输出结果:

    Image

    array容器简介

    1. //形如:
    2. //array<type,number> arrayName{初始化 or not};
    3. array<int,3> arr{9,8,7};

    C++支持类模板参数推导,如下面的形式(但是在我的VS2022,C++14标准下显示错误(缺少参数列表[汗颜]))

    array arr{9,8,7};
    

    后来发现类模板参数推导(CTAD)是C++17的新规范QWQ.

    结构化绑定(C++17)

    结构化绑定允许声明多个变量,这些变量使用数组,结构体,pair或元组

    1. //结构化绑定必须需要使用auto关键,声明的变量数量必须与右侧表达式中的值数量匹配
    2. array values {11,22,33};
    3. auto [x,y,z]{values};
    4. //如果所有非静态成员都是公有的,也可以将结构化绑定用于结构体
    5. #include<iostream>
    6. #include<array>
    7. using namespace std;
    8. struct Point
    9. {
    10. int _x, _y, _z;
    11. };
    12. int main()
    13. {
    14. Point point{1,2,3};
    15. auto [x, y, z] {point};
    16. cout << "Point._x : " << x <<endl;
    17. cout << "Point._y : " << y << endl;
    18. cout << "Point._z : " << z << endl;
    19. }

    输出结果:

    Image

    export关键字

    为了访问其他编译单元(如另一代码文件)中的变量或对象,对普通类型(包括基本数据类、结构和类),可以利用关键字extern,来使用这些变量或对象时;但是对模板类型,则必须在定义这些模板类对象和模板函数时,使用标准C++新增加的关键字export(导出/出口/输出)。例如:

    extern int n;

    extern struct Point p;

    extern class A a;

    export template class Stack s;

    export template void f (T& t) {……}

    一般是在头文件中给出类的定义或全局函数的声明信息,而在代码文件中给出具体的(类成员函数或全局函数的)函数定义。然后在多个用户代码文件中包含该头文件后,就可以使用其中定义或声明的类和函数。头文件中一般不包含变量、结构和类对象的定义,因为这样可能会导致重复定义的编译错误。解决办法是,在某个代码文件中进行定义,在其他用户代码文件中用extern来引用它们。

    但是对模板类型,则可以在头文件中,声明模板类和模板函数;在代码文件中,使用关键字export来定义具体的模板类对象和模板函数;然后在其他用户代码文件中,包含声明头文件后,就可以使用该这些对象和函数了。

    1. export class AirlineTicket
    2. {
    3. public:
    4. AirlineTicket();//没有返回值并且与类名相同的是构造函数
    5. ~AirlineTicket();//前面加上~的是析构函数
    6. double calculatePriceInDollars();
    7. std::string getPassengerName();
    8. void setPassengerName(std::string name);
    9. int getNumberOfMiles();
    10. void setNumberOfMiles(int miles);
    11. bool hasEliteSuperRewardsStatus();
    12. void setHasEliteSuperRewardsStatus(bool status);
    13. private:
    14. std:: string m_passengerName;
    15. int m_numberOfMiles;
    16. bool m_hasEliteSuperRewardsStatus;
    17. };

    构造函数初始化器

    1. AirlineTicket::AirlineTicket():
    2. m_passengerName {"Unknow Passenger"},
    3. m_numberOfMiles {0},
    4. m_hasEliteSuperRewardsStatus{false}
    5. {}

    在构造函数之后加冒号

    类内初始化(C++11)

    如果构造函数仅仅只是初始化数据成员,而不进行其他的事情实际上就没有必要使用构造函数。

    可以直接在类定义中直接初始化数据成员

    1. private:
    2. std::string m_passengerName {"Unknow Passenger"};
    3. int m_numberOfMiles {0};
    4. bool m_hasEliteSuperRewardsStatus{false};

    统一初始化(C++11)

    1. struct CircleStruct{
    2. int x,y;
    3. double radius;
    4. }
    5. class CircleClass{
    6. public:
    7. CircleClass(int x,int y,double radius):
    8. m_x{x},m_y{y},m_radius{radius}{}
    9. private:
    10. int m_x,m_y;
    11. double m_radius;
    12. }

    在C++11之前对他们进行初始化是不相同的

    1. CircleStruct myCircle1 = {10,10,2.5};
    2. Circle myCircle1(10,10,2.5);

    在C++11之后一律允许使用{...}初始化对象。

    指派初始化器(C++20)

    1. struct Employee{
    2. char firstInitial;
    3. char lastInitial;
    4. int employeeNumber;
    5. int salary{75000};
    6. }
    7. //使用指派初始化器
    8. Employee anEmployee {
    9. .firstInitial = 'J',
    10. .lastInitial = 'D',
    11. .employeeNumber = 42,
    12. .salary = 80000;
    13. }

    使用指派初始化器可以跳过初始化某些成员。

    1. Employee anEmployee {
    2. .firstInitial = 'J',
    3. .lastInitial = 'D',
    4. }

    按照上面的方式 employeeNumber 初始化为 0 salary 初始化为 75000

  • 相关阅读:
    论文精读:YOLOv4: Optimal Speed and Accuracy of Object Detection
    C++二分算法:找到最接近目标值的函数值
    网络安全岗位介绍——售前工程师
    如何选购过孔滑环
    2022年6月第十三届蓝桥杯大赛软件赛全国决赛C++A组题解
    蓝桥杯练习系统(算法训练)ALGO-979 移动
    类和对象6:相关内置函数
    DSP_TMS320F28335_优秀的串口通信框架
    界面控件Telerik UI for ASP. NET Core教程 - 如何为网格添加上下文菜单?
    【LInux】进程管理
  • 原文地址:https://blog.csdn.net/m0_69824302/article/details/134220894