Why Group Data Together
So far every variable has stood on its own: an int here, a string there. But real programs deal with things made of several pieces - a point has an x and a y, a student has a name, an age, and a GPA. Passing those around as loose, separate variables is error-prone; nothing ties them together, and a function that needs all three must take all three parameters.
A struct fixes this. It defines a new type that bundles related variables - its members - into one unit. Once defined, you treat the whole bundle as a single value you can store, copy, and pass to functions.
You reach each member with the dot operator (s.name, s.age). The semicolon after the closing } of a struct definition is required - leaving it off is one of the most common beginner compile errors in C++.
Initializing a Struct
Assigning each field by hand works, but it's verbose and easy to forget a member. The cleaner option is aggregate initialization: list the values in braces, in the same order the members were declared.
Watch out for the empty default: Point p; (no braces) leaves x and y holding garbage values, because built-in members aren't auto-zeroed. Point p{}; value-initializes them to 0. Prefer the braces. You can also bake in defaults right in the definition, so even Point p; starts clean:
Structs as Function Parameters
A struct is a single value, so a function can take one parameter instead of three. Just remember that passing a struct by value copies every member. For anything bigger than a couple of ints, pass by const reference to skip the copy - the same rule you saw on the references page.
Returning a whole struct from a function is the idiomatic way to hand back several values at once - far cleaner than juggling multiple output references.
Adding Member Functions and Constructors
A struct isn't limited to data. It can hold member functions that operate on its own members, and a constructor that initializes the object the moment it's created. This is where a struct starts to look like a small object with behavior.
Inside a member function the members are accessed by name (width, height) - they refer to this object's copy. Marking area() const tells the compiler the function only reads the object, which lets you call it on const Rectangle values too. Constructors are a topic in their own right, including that : width(w) initializer-list syntax - the constructors page goes deep.
Struct vs. Class: The Real Difference
You may have heard that "structs are for data, classes are for objects." That's a convention, not a language rule. In C++ a struct and a class are almost the same thing - the only built-in difference is the default access level.
struct S {
int x; // public by default
};
class C {
int x; // private by default
};
Members of a struct are public unless you mark them otherwise; members of a class start out private. That's it - both can have constructors, member functions, inheritance, and everything else. You can even add explicit access specifiers to a struct to hide members:
The practical takeaway: use struct for transparent bundles of data where every field is meant to be touched freely (a Point, a Color, a config record), and reach for class when you want to protect internal state behind a public interface. The compiler treats them the same; the keyword just signals your intent.
Arrays and Vectors of Structs
Because a struct is an ordinary type, you can put many of them in an array or a vector and loop over them like any other value.
Note the nested braces: each {"Keyboard", 49.99} aggregate-initializes one Product, and the outer braces build the vector. Using const Product& in the range-based loop avoids copying each struct on every iteration - drop the & and you'd duplicate every element needlessly.
Next: Enums
Structs let you build a type out of several values bundled together. The next chapter goes the other direction: an enum defines a type that can hold exactly one value out of a small, named set - perfect for things like Color::Red, Direction::North, or a state machine's status. You'll see how enum class gives you readable, type-safe constants that pair naturally with the structs and classes you're now building.
Frequently Asked Questions
What is a struct in C++?
A struct is a user-defined type that groups several related variables (called members) under one name. Instead of juggling separate string name, int age, and double gpa variables, you bundle them into a single Student type and pass that one object around. A struct can also hold member functions and constructors - in modern C++ it's a full-fledged class whose members are public by default.
What is the difference between struct and class in C++?
Technically only the default access level: members of a struct are public unless you say otherwise, while members of a class are private by default. The same is true for inheritance. Everything else - constructors, member functions, methods, inheritance - works identically. By convention, programmers reach for struct for plain data bundles and class for types with invariants and hidden internals.
How do you initialize a struct in C++?
The simplest way is aggregate initialization with braces in member order: Point p{3, 4};. You can also assign each field by hand with the dot operator (p.x = 3;), give members default values in the definition (int x = 0;), or write a constructor so the struct sets itself up. Brace initialization is preferred because it won't silently leave fields uninitialized.