Structs and Aggregate Initialization

Discover the role of structs, how they differ from classes, and how to initialize them without requiring a constructor.
This lesson is part of the course:

Intro to C++ Programming

Become a software engineer with C++. Starting from the basics, we guide you step by step along the way

Free, Unlimited Access
3D art showing a female character
Ryan McCombe
Ryan McCombe
Updated

In some of our class examples, we suggested that our objects should have properties like WorldPosition - where that character currently exists in the world.

In 3D environments, this is represented as three separate numbers, or coordinates, typically called x, y, and z

We could store this as 3 separate variables. But it is usually much better to package these coordinates together, so they can be used and transferred as a single object.

This means we need to create a new custom type of data.

Creating Structs

We've already seen how to define a new data type using a class, but there is an alternative - something called a structure, or struct:

struct Vector3 {
  float x;
  float y;
  float z;
}

What is a Vector3?

A vector is a term taken from maths - it simply refers to a container for storing a collection of related variables - often numbers.

Vectors are the most common way of representing position and directions within a space we’re simulating. Therefore, a custom Vector3 type (sometimes abbreviated to Vec3) is typically one of the most fundamental types within graphics applications.

The 3 in the type name indicates it is a 3-dimensional vector, used to store a position in a 3D environment.

We build out our knowledge and application of vectors in several lessons throughout the rest of the course.

Test your Knowledge

Defining Structs

How could we create a struct that represents a combat ability?

Structs vs Classes (Technical)

You may be thinking this problem could also be solved by classes. This is completely true - Vector3 could indeed be a class.

In C++, structs and classes are almost identical. The only difference between a struct and a class is that, by default, members of a struct are public whilst in a class, they are private.

Aside from that, there is no difference - we create and use structs in the same way we do classes. Structs can have functions, constructors, destructors, and more. and everything else that a class has.

Everything we have learned (and will learn in the future) about classes also applies to structs.

Structs vs Classes (Semantic)

Even though structs and classes are technically almost identical, the C++ community still attaches semantic differences to the two concepts.

The general sentiment is that structs are for creating simpler types, whilst classes are for creating more powerful types.

Google's style guide offers a good example, and many developers/companies have a similar approach:

  • structs should be used for passive objects that carry data, but lack any functionality other than access/setting the data members.
  • All fields must be public, and accessed directly rather than through getter/setter methods.
  • Methods should not provide behavior but should only be used to set up the data e.g., constructor, Initialize(), Reset().
  • If more functionality is required, a class is more appropriate.
  • If in doubt, make it a class.

Moreover, the difference between classes and structs may become slightly more important when working within the context of other ecosystems, such as a game engine.

For example, in Unreal, structs have legitimate technical limitations that effectively enforce the "structs are for simple things" convention.

Test your Knowledge

Structs vs Classes

What is the main difference between a struct and a class?

Aggregate Initialization

Aggregate initialization is a feature that simplifies the process of initializing simple objects.

It allows us to initialize the members of a struct or an array directly without needing to explicitly define a constructor.

Consider our earlier Vector3 struct:

struct Vector3 {
  float x;
  float y;
  float z;
};

In a typical scenario, you would need to define a constructor to initialize these values. However, with aggregate initialization, you can directly assign values to x, y, and z when creating an instance of Vector3. Here's what it looks like:

struct Vector3 {
  float x;
  float y;
  float z;
};

int main() {
  Vector3 Position {1.9, 2.6, 0.3};
}

In this example, Position is an instance of Vector3 with x, y, and z initialized to 1.9, 2.6, and 0.3 respectively.

Aggregate initialization is not always available. We cover it in detail in the advanced course, but for now, we should note that it is more likely to be an option when our types are simple.

As such, if we’re adopting the convention of structs being for simple types, aggregate initialization is much more likely to be available to instantiate structs than classes.

With a type that uses more advanced features - such as private sections - aggregate initialization is less likely to be an option, and we need to go back to defining an appropriate constructor manually.

Summary

In this lesson, we delved into the concept of structs in C++, exploring their technical and semantic differences from classes. Here are the key takeaways:

  • Structs offer a simpler alternative to classes for bundling data together.
  • By default, members of a struct are public, unlike in a class where they are private. This is the only technical difference between the two.
  • Structs are generally used for passive objects that carry data, without complex behaviors or functionalities.
  • Aggregate initialization allows for the simple and direct assignment of values to the members of a struct, enhancing code brevity and clarity.
  • The concept of vectors, specifically Vector3, was introduced as a fundamental type in graphics applications, demonstrating a practical use of structs.

Preview of the Next Lesson: Operator Overloading

Previously, we've seen how built-in objects like int and bool allowed us to use operators like + and >= to interact with them.

int SomeInt { 2 };
int AnotherInt { SomeInt + 5 };
bool SomeBool { AnotherInt >= 10 };
bool AnotherBool { !MyBoolean };

It would be useful if we had a way to define operators for our custom types too. For example, we'll need the ability to add two of our vectors together.

We could define a function on our class or struct to facilitate that. It could allow us to add vectors together by doing something like this:

MyFirstVector.Add(MySecondVector);

But our code would be more expressive if we could just do this instead:

MyFirstVector + MySecondVector;

In the next lesson, we can see how we can update our classes and structs to make these types of interactions possible.

Was this lesson useful?

Next Lesson

Operator Overloading

This lesson introduces operator overloading, a fundamental concept to create more intuitive and readable code by customizing operators for user-defined types
3D art showing a fantasy character
Ryan McCombe
Ryan McCombe
Updated
Lesson Contents

Structs and Aggregate Initialization

Discover the role of structs, how they differ from classes, and how to initialize them without requiring a constructor.

3D art showing a progammer setting up a development environment
This lesson is part of the course:

Intro to C++ Programming

Become a software engineer with C++. Starting from the basics, we guide you step by step along the way

Free, Unlimited Access
Classes and Structs
3D art showing a progammer setting up a development environment
This lesson is part of the course:

Intro to C++ Programming

Become a software engineer with C++. Starting from the basics, we guide you step by step along the way

Free, unlimited access

This course includes:

  • 56 Lessons
  • Over 200 Quiz Questions
  • 95% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Next Lesson

Operator Overloading

This lesson introduces operator overloading, a fundamental concept to create more intuitive and readable code by customizing operators for user-defined types
3D art showing a fantasy character
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved