Get Started Now

Intro to C++ Programming

Starting from the fundamentals, become a C++ software engineer, step by step.

LATEST UPDATES

Screenshot from Cyberpunk 2077
Module One

Intro to C++ Programming

Starting from the basics, become a C++ software engineer, step by step

Screenshot from Cyberpunk 2077
Screenshot from The Witcher 3: Wild Hunt
Screenshot from Warhammer: Total War
Screenshot from Cyberpunk 2077
Module Two

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects

Screenshot from Cyberpunk 2077
Screenshot from The Witcher 3: Wild Hunt
Screenshot from Warhammer: Total War
Screenshot from Cyberpunk 2077
Coming Soon

SDL and C++ Development

Learn C++ and SDL development by recreating classic retro games

Screenshot from Cyberpunk 2077
Screenshot from The Witcher 3: Wild Hunt
Screenshot from Warhammer: Total War
MOST POPULAR

Errors and Assertions

Learn how we can ensure that our application is in a valid state using compile-time and run-time assertions.
Abstract art representing computer programming
Ryan McCombe
Updated
Published

Whenever we write a function that accepts arguments, we generally have some assumptions about those arguments. For example, if we have a function that takes a pointer, we might assume that the pointer is not a nullptr.

These are sometimes called "preconditions" - things that our function assumes to be true before it starts performing its task.

Exceptions: throw, try and catch

This lesson provides an introduction to exceptions, detailing the use of throw, try, and catch.
Abstract art representing computer programming
Ryan McCombe
Updated
Published

In the previous lesson, we introduced the assert() macro, which gives us a way to check for errors at run time. This is useful for simple scenarios but, for more complex software, we also need a more powerful option. Specifically, we’d like to be able to do things like:

  • Detect and recover from errors, potentially elsewhere in the call stack - that is, having our functions throw an error that is detected within one of the calling functions
  • Generate errors that are represented by full-fledged objects. These give error handling code the ability to fully understand and react to the errors, by accessing variables and calling functions on the error object.

To implement this capability, we have dedicated keywords within C++, and many similar languages: throw, try, and catch.

Exception Types

Gain a thorough understanding of exception types, including how to throw and catch both standard library and custom exceptions in your code
Abstract art representing computer programming
Ryan McCombe
Updated
Published

Rather than throwing simple primitive objects like integers and strings, our exceptions get much more powerful when we throw types that are specifically designed to represent errors.

This gives us the ability to define variables and class functions on our error objects, giving our throw blocks many more options to inspect and react to the exception.

Copy Semantics and Return Value Optimization

Learn how to control exactly how our objects get copied, and take advantage of copy elision and return value optimization (RVO)
Illustration representing computer hardware
Ryan McCombe
Updated
Published

When we’re dealing with dynamic memory and smart pointers, interesting questions and problems soon begin to arise.

Consider the following setup. We have Character objects who carry Sword objects. When a character is created, it creates a sword for itself, and it dutifully cleans up the sword when it gets destroyed:

struct Sword {};

class Character {
 public:
  Character() : Weapon{new Sword{}} {}
  ~Character() { delete Weapon; }

  Sword* Weapon;
};

However, problems will soon arise once we begin using this class. We’ll introduce some of the problems, and how to solve them throughout this lesson.

Move Semantics

Learn how we can improve the performance of our types using move constructors, move assignment operators and std::move()
Illustration representing computer hardware
Ryan McCombe
Updated
Published

In our previous lesson, we saw how we could implement copy constructors and operators to implement copy semantics. Here, we’re going to implement move semantics.

However, it’s helpful to first understand why we need this feature at all, so let’s introduce some of the problems it’s designed to solve.

Often, the objects we create will need to store other objects within them. These sub-objects can often be containers such as std::vector objects, which themselves may contain many thousands of their own sub-objects.

For example, if we’re working with databases, we might have objects that are storing thousands of other objects, representing entries in that database.

If we were making a video game, we might have an object representing an entire level, comprised of thousands of sub-objects of various types (enemies, environment art, audio, and so on)

Value Categories (L-Values and R-Values)

A straightforward guide to l-values and r-values, aimed at helping you understand the fundamentals
Illustration representing computer hardware
Ryan McCombe
Updated
Published

In the previous lesson on move semantics, we introduced a new type of reference, which uses the && syntax:

#include <iostream>

struct Resource {
  // Copy Constructor
  Resource(const Resource& Source) {}

  // Move Constructor
  Resource(Resource&& Source) {}
};

In this lesson, we’ll explore what this means in more detail, by introducing value categories.

Building SDL2 from a Subdirectory (CMake)

A step-by-step guide on setting up SDL2 and useful extensions in a project that uses CMake as its build system
Vector illustration representing computer programming
Ryan McCombe
Updated
Published

In this lesson, we’ll get SDL installed, along with two extensions which we’ll need later in this chapter.

  • SDL is a cross-platform library that allows us to create windows, access input devices, and create graphics.
  • SDL_image is an extension that allows us to work with images in all the common formats, such as jpeg and png
  • SDL_ttf is an extension that we can use to render text at run-time

This setup guide is designed for projects that use the CMake build system, where the SDL libraries will be stored in a subdirectory of our project.

Building SDL2 from Source (GCC and Make)

This guide walks you through the process of compiling SDL2, SDL_image, and SDL_ttf libraries from source
Vector illustration representing computer programming
Ryan McCombe
Updated
Published

In this lesson, we’ll get SDL installed, along with two extensions which we’ll need later in this chapter.

  • SDL is a cross-platform library that allows us to create windows, access input devices, and create graphics.
  • SDL_image is an extension that allows us to work with images in all the common formats (jpeg, png, etc)
  • SDL_ttf is an extension that we can use to render text at run-time

This setup guide downloads the source code for the libraries and compiles them on our local machine. We then demonstrate how to add these libraries to projects that use either Xcode or CMake

Smart Pointers and std::unique_ptr

An introduction to memory ownership using smart pointers and std::unique_ptr in C++
Illustration representing computer hardware
Ryan McCombe
Updated
Published

In the world of long-running, complex software like online game servers, managing memory efficiently is critical.

Imagine handling hundreds of thousands of objects without a hitch, for weeks or even months. Here, even a tiny memory leak can snowball into a major issue.

That's where strategic memory management comes in. Instead of littering your code with haphazard delete calls, we adopt a system of ownership. In this system, objects own other objects, creating a hierarchical structure of responsibility.

This approach not only cleans up our code but also ensures that when one object is deleted, all its dependents are automatically cleaned up too.

Let's dive into how we can simplify and strengthen our memory management with this smart system of ownership.

Shared Pointers using std::shared_ptr

An introduction to shared memory ownership using std::shared_ptr
Illustration representing computer hardware
Ryan McCombe
Updated
Published

So far in this section, we’ve coverered how smart pointers are tools for managing dynamically allocated memory, ensuring that memory is automatically deallocated when it is no longer needed.

The C++ standard library provides a few variations of smart pointers. std::unique_ptr and std::shared_ptr are the most commonly used, but they serve different purposes:

Unique Pointers

Unique pointers, such as std::unique_ptr enforces unique ownership of the memory resource it manages. It implies that only one unique pointer can point to a specific resource at any time.

When the std::unique_ptr is destroyed or revokes its ownership through the std::move(), release() or reset() methods, the resource it points to is automatically deallocated. This type of smart pointer is lightweight and efficient, making it an ideal choice for most single-owner scenarios.

We covered unique pointers in detail a dedicated lesson:

Shared Pointers

Unlike std::unique_ptr, std::shared_ptr allows multiple pointers to share ownership of a single resource. The resource is only deallocated when the last std::shared_ptr pointing to it is destroyed or reset.

This shared ownership is managed through reference counting - an internal mechanism that keeps track of how many std::shared_ptr instances are managing the same resource. This comes at a performance cost, so in general, std::unique_ptr, should be our default choice of smart pointer.

However, there are scenarios where an object needs to be accessed and managed by multiple owners. In such cases, std::shared_ptr becomes invaluable, and we’ll cover it in detail in this lesson.

Similar to the previous lesson, we’ll be using the following Character class to demonstrate how shared pointers work.

It has a simple constructor and destructor that logs when objects are created and destroyed, so we can better understand when these steps happen:

Module One
3D art showing a progammer setting up a development environment

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
Module Two
A computer programmer

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Free, unlimited access

This course includes:

  • 124 Lessons
  • 550+ Code Samples
  • 96% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Coming Soon
sdl2-promo.jpg

Game Dev with SDL2

Learn C++ and SDL development by creating hands on, practical projects inspired by classic retro games

Under Construction
Get Started Now

Intro to C++ Programming

Starting from the fundamentals, become a C++ software engineer, step by step.

Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved