Modern C++ gives you powerful tools for expressing data clearly, safely, and efficiently. This chapter teaches you how to think about types, structs, and data layout the way professional engineers do — especially in systems where performance, clarity, and modularity matter.
We will explore how data is represented in memory, how struct design affects performance, and how to build clean, predictable types that integrate naturally into larger systems.
In many languages, data layout is abstracted away. In C++, it is part of the language’s identity.
Data layout affects:
Even if you never write low level code, understanding data layout makes you a better C++ engineer.
Modern C++ encourages you to think in terms of three broad categories:
This chapter focuses on
In modern C++:
struct → public by defaultclass → private by defaultThat’s the only difference.
Use
struct vec3
{
float x, y, z;
};
Use
class Texture
{
public:
Texture(const std::string& path);
~Texture();
private:
GLuint id;
};
This simple convention makes code more readable and intentional.
A good struct:
Example:
struct transform
{
vec3 position;
vec3 rotation;
vec3 scale;
};
This struct is predictable, easy to serialize, and easy to use.
C++ aligns data for performance. This can introduce
Example:
struct Example
{
char a; // 1 byte
int b; // 4 bytes
char c; // 1 byte
};
Memory layout might be:
a _ _ _ b b b b c _ _ _
Padding ensures proper alignment for
What this affects:
How to reduce padding: Group members by size:
struct ExampleOptimized
{
int b;
char a;
char c;
};
This produces tighter layout:
b b b b a c _ _
A POD type:
POD types are ideal for:
Example:
struct vertex
{
float x, y, z;
float nx, ny, nz;
float u, v;
};
This struct is POD and safe to memcpy.
Math types are the backbone of graphics and simulation.
Example:
struct vec3
{
float x, y, z;
vec3() = default;
vec3(float x, float y, float z)
: x(x), y(y), z(z) {}
};
These types should be:
Avoid heap allocation inside math types.
Modern C++ uses clear rules:
void Move(vec3 delta);
void SetTransform(const transform& t);
void AttachChild(Node* child);
void Update(transform& t);
These conventions make APIs predictable.
Good type design:
Example of clear design:
struct Color
{
float r, g, b, a;
};
Example of unclear design:
class Color
{
private:
float* data; // heap allocation
public:
Color();
~Color();
};
The second version is harder to reason about and unnecessary.
In this chapter, we saw:
These principles form the foundation for the architectural chapters that follow.