本内容参考C++20高级编程
- //形如
- int myArray[3]{2};
一个比较新颖的获取C风格数组大小的函数std::size(),返回size_t类型(在中定义的无符号整数)
- #include <iostream>
- using namespace std;
-
- int main()
- {
- int myArray[5] = { 0 };
- size_t arraySize{size(myArray)};
- cout << arraySize;
- return 0;
- }
输出结果:

Image
- //形如:
- //array<type,number> arrayName{初始化 or not};
- array<int,3> arr{9,8,7};
C++支持类模板参数推导,如下面的形式(但是在我的VS2022,C++14标准下显示错误(缺少参数列表[汗颜]))
array arr{9,8,7};
后来发现类模板参数推导(CTAD)是C++17的新规范QWQ.
结构化绑定允许声明多个变量,这些变量使用数组,结构体,pair或元组
- //结构化绑定必须需要使用auto关键,声明的变量数量必须与右侧表达式中的值数量匹配
- array values {11,22,33};
- auto [x,y,z]{values};
-
- //如果所有非静态成员都是公有的,也可以将结构化绑定用于结构体
- #include<iostream>
- #include<array>
- using namespace std;
-
- struct Point
- {
- int _x, _y, _z;
- };
-
- int main()
- {
- Point point{1,2,3};
- auto [x, y, z] {point};
- cout << "Point._x : " << x <<endl;
- cout << "Point._y : " << y << endl;
- cout << "Point._z : " << z << endl;
- }
输出结果:

Image
为了访问其他编译单元(如另一代码文件)中的变量或对象,对普通类型(包括基本数据类、结构和类),可以利用关键字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来定义具体的模板类对象和模板函数;然后在其他用户代码文件中,包含声明头文件后,就可以使用该这些对象和函数了。
- export class AirlineTicket
- {
- public:
- AirlineTicket();//没有返回值并且与类名相同的是构造函数
- ~AirlineTicket();//前面加上~的是析构函数
- double calculatePriceInDollars();
- std::string getPassengerName();
- void setPassengerName(std::string name);
- int getNumberOfMiles();
- void setNumberOfMiles(int miles);
- bool hasEliteSuperRewardsStatus();
- void setHasEliteSuperRewardsStatus(bool status);
- private:
- std:: string m_passengerName;
- int m_numberOfMiles;
- bool m_hasEliteSuperRewardsStatus;
- };
- AirlineTicket::AirlineTicket():
- m_passengerName {"Unknow Passenger"},
- m_numberOfMiles {0},
- m_hasEliteSuperRewardsStatus{false}
- {}
在构造函数之后加冒号
如果构造函数仅仅只是初始化数据成员,而不进行其他的事情实际上就没有必要使用构造函数。
可以直接在类定义中直接初始化数据成员
- private:
- std::string m_passengerName {"Unknow Passenger"};
- int m_numberOfMiles {0};
- bool m_hasEliteSuperRewardsStatus{false};
- struct CircleStruct{
- int x,y;
- double radius;
- }
-
- class CircleClass{
- public:
- CircleClass(int x,int y,double radius):
- m_x{x},m_y{y},m_radius{radius}{}
- private:
- int m_x,m_y;
- double m_radius;
- }
在C++11之前对他们进行初始化是不相同的
- CircleStruct myCircle1 = {10,10,2.5};
- Circle myCircle1(10,10,2.5);
在C++11之后一律允许使用{...}初始化对象。
- struct Employee{
- char firstInitial;
- char lastInitial;
- int employeeNumber;
- int salary{75000};
- }
-
- //使用指派初始化器
- Employee anEmployee {
- .firstInitial = 'J',
- .lastInitial = 'D',
- .employeeNumber = 42,
- .salary = 80000;
- }
使用指派初始化器可以跳过初始化某些成员。
- Employee anEmployee {
- .firstInitial = 'J',
- .lastInitial = 'D',
- }
按照上面的方式 employeeNumber 初始化为 0 salary 初始化为 75000