Structures
Just like in C you have structs which are also commonly called open classes. Structs can only hold public attributes and no functions.
Struct packing
When working with structs it is however important to know how the memory is used. A struct declaration allocates a contiguous memory for the collection. It uses a multiple of the largest attribute in memory which is needed for all attributes + any padding needed. It uses the largest attribute as alignment for easier access. which can lead to the order of your attributes having an influence on how much the object takes up in memory.
struct top { // total of 16 bytes
char* p; // 8 bytes on 64 bit, 4 on 32 bit system
int i; // 4 bytes
short s; // 2 bytes
char c; // 1 byte
// 1 byte padding
}
struct bottom { // total of 24 bytes
char c; // 1 byte
// 7 bytes padding
char* p; // 8 bytes
short s; // 2 bytes
int i; // 4 bytes
// 2 bytes padding
}
You can check the alignment of a struct with alignof(top)
. You can also change the default behaviour with either #pragma pack(1)
to use 1 byte alignment and then after defining the struct restet it back to default with #pragma pack()
. Or you can use struct alignas(4) S{};
.
Bit fields
Bitfields can only be used inside structured data types, i.e. struct, class, and union types and with integer types. The purpose is to allow you to pack multiple members inside a single byte.
struct halfbyte_t {
unsigned int half1: 4;
unsigned int half2: 4;
} halfbyte;
This declares a variable named halfbyte that contains two 4-bit members, which will be packed into a single 8-bit byte, rather than having to use 2 bytes if you just declared them unsigned char. 1-bit fields are especially useful if you have lots of boolean flags in a structure, since you don't have to have a separate byte for each flag.