0 引言
struct
union
enum
enum class
1 struct
type | 特点 |
---|---|
数组 | 相同类型元素的集合 |
结构体 | 任意类型元素的集合 |
默认情况下,比较运算符不适用于结构体,除非用户自己定义这些运算符
struct对象中,成员按照生命的顺序依次存放。注意字节对齐。
如果有空洞,最终计算的sizeof(),可能就不是简单的累加。
类型名字只要出现就能使用,eg.
struct Link {
Link* prev;
Link* succ;
};
但是只有声明全部完成后才能声明对象,eg.
struct No_good {
No_good member; // 递归定义,无效
};
可以在真正定义一个struct类型之前使用其名字,只要中间不调用成员的名字和结构大小即可。
备注:C的结构体定义
typedef struct Name {
// ...
} NameA;
2 struct vs class
struct是class的一种,与常见class不同的是,struct 成员默认是public
struct可以包含成员函数,比如,构造函数。
若仅按照默认的初始化顺序初始化结构体成员,不需要构造函数;反之,若需要改变实参的顺序、检验实参的有效性、修改实参或者建立不变式,则应编写专门的构造函数。
3 struct vs array
std::array是一种struct。
template<typename T, size_t N>
struct array { // 简化版本
T elem[N];
T* begin() noexcept {return elem;}
const T* begin() const noexcept {return elem;}
T* end() noexcept {return elem + N;}
const T* end() const noexcept {return elem + N;}
constexpr size_t size() noexcept;
T& operator[](size_t n) {return elem[n];}
const T& operator[](size_t n) const {return elem[n];}
T* data() noexcept {return elem;}
const T* data() const noexcept {return elem;}
// ...
};
与内置数组相比,std::array的优势:
首先,std::array是一种真正的对象类型(可以进行赋值操作),其次,不会隐式地转换成指向元素的指针。
4 类型等价
对于两个struct,即使成员相同,仍是不同的类型。struct本身的类型与其成员不能混为一谈。
5 POD
plain old data
指能被“仅当作数据”处理的对象,程序员无需顾及类布局的复杂性以及用户自定义的构造、拷贝和移动语义。
POD对象:
不具有复杂的布局;
不具有非标准(用户自定义)的拷贝语义;
含有一个最普通的默认构造函数。
POD必须属于下列类型的对象:
标准布局类型;
平凡可拷贝类型;
具有平凡默认构造函数的类型
平凡类型trivial type:
一个平凡默认构造函数;
平凡拷贝和移动操作;
当一个默认构造函数无须执行任何实际操作时(若需定义一个默认构造函数,使用=default),则认为是平凡的。
一个类型具有非标准布局的条件:
- 含有一个非标准布局的非static成员或基类;
- 包含virtual函数;
- 包含virtual基类;
- 含有引用类型的成员;
- 其中的非静态数据成员有多种访问修饰符;
- 阻止了重要的布局优化:
- 在多个基类中都含有非static数据成员,或者在派生类和基类中都含有非static数据成员
- 基类类型与第一个非static数据成员的类型相同
标准布局类型是指与C的布局兼容的类型,并且能被常规的C++应用程序二进制接口(ABI)处理。
判断POD类型的方法
// <type_traits>
// 标准库类型属性谓词
std::is_pod<T>::value
6 域
bit-field
struct PPN {
uint PFN : 22;
int : 3;
uint CCA : 3;
bool nonreachable : 1;
bool dirty : 1;
// ...
};
C++允许未命名的域。
域必须是整型或枚举类型。
注意:用域将几个变量打包在一个字节中并不一定能节省空间。虽然节省了数据空间,但是负责管理和操作这些变量的代码在绝大多数机器上都会更长。
7 联合体
特殊的struct
使用union的目的一般是使数据更紧密,但是实际上并没有提供多少。
尽可能少用union
8 union 与 class
可以使用一组派生类替代union,避免空间的浪费。
9 枚举
enum class 限定作用域的强类型枚举
枚举类型:基础类型,必须是一种带符号或无符号的整型,默认int