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
Capstone Project

Building Minesweeper with C++ and SDL2

Apply what we learned to build an interactive, portfolio-ready capstone project using C++ and the SDL2 library

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

Professional C++

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

Pointers to Members

Learn how to create pointers to class functions and data members, and how to use them
Abstract art representing computer programming
Ryan McCombe
Published

Previously, we’ve seen how function pointers, and first-class functions in general, give us a lot of flexibility in designing our programs.

In the following example, our Party class has a for_each() method which accepts a function argument. It then invokes that function for every Player in the Party:

#include <iostream>

class Player {/*...*/}; class Party { public: void for_each(auto Func) { Func(PlayerOne); Func(PlayerTwo); Func(PlayerThree); } private: Player PlayerOne{"Roderick"}; Player PlayerTwo{"Anna"}; Player PlayerThree{"Steve"}; };

This allows the external code to execute an action for each Player. This design gives us a useful separation: the Party class implements and controls the iteration process, whilst external code can specify the behavior they want to happen on each iteration.

Below, our program uses a function pointer to provide behavior defined within the Log() function:

#include <iostream>

class Player {/*...*/};
class Party {/*...*/}; void LogName(Player& P) { std::cout << P.Name << '\n'; } int main() { Party MyParty; MyParty.for_each(LogName); }
Roderick
Anna
Steve

In this lesson, we’ll expand our techniques to include member function pointers - that is, pointers to functions that are part of a class or struct:

#include <iostream>

class Player {
 public:
  void LogName() {
    std::cout << Name << '\n';
  }
  
  std::string Name;
};

class Party {/*...*/}; int main() { Party MyParty; // We want to use the `Player::LogName()` function MyParty.for_each(/* ??? */); }

This is more difficult than we might expect, so let’s break down all the complexities.

SDL2 Timers and Callbacks

Learn how to use callbacks with SDL_AddTimer() to provide functions that are executed on time-based intervals
Abstract art representing computer programming
Ryan McCombe
Published

In this lesson, we’ll introduce SDL’s timer mechanisms, which interact with function pointers to implement commonly required functionality. The capabilities this unlocks primarily fall into two categories:

  • Performing an action after a delay, such as restricting the use of an ability until some time has passed
  • Performing an action on a repeating interval, such as spawning a new enemy every few seconds

To use SDL timers, we should pass the SDL_INIT_TIMER flag to SDL_Init():

SDL_Init(SDL_INIT_TIMER);

We can combine multiple initialization flags using the bitwise | operator:

SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);

Delegates and the Observer Pattern

An overview of the options we have for building flexible notification systems between game components
Abstract art representing programming
Ryan McCombe
Published

The biggest challenge we have when designing our program is managing how different components communicate with each other. If we manage this poorly, the complexity of our project will quickly get out of hand, making it extremely difficult to add new features or even understand what is going on.

However, if we manage this well, our project will stay understandable and easy to work with, even as we add more and more features.

Imagine we have a Player object and a UIElement class. The UIElement needs to be displayed when our Player is defeated. Let’s review some of the ways we can make this happen

Function Binding and Partial Application

This lesson covers function binding and partial application using std::bind(), std::bind_front(), std::bind_back() and std::placeholders.
Abstract art representing computer programming
Ryan McCombe
Updated
Published

Earlier in the chapter, we introduced the concept of partial application. With partial application, we provide only some of a function’s required arguments - the remaining arguments are provided later, elsewhere in our code.

Being able to implement this approach gives us more flexibility in our designs, and is sometimes required. We introduced an example where we wanted to determine if a Player object was a minimum level but, because of constraints in our design, we were not able to provide the Player and MinimumLevel at the same time.

We solved this using a functor. We provided the MinLevel as a constructor argument, where it then got saved to a member variable. We then later provided the Player object as an argument to the () operator.

A simplified implementation of the full example we introduced in the Functors lesson is below:

#include <iostream>

struct Player {
  int GetLevel() const { return 45; }
};

struct LevelChecker {
  int MinLevel {50};
  bool operator()(const Player& P) {
    return P.GetLevel() >= MinLevel;
  }
};

int main() {
  Player PlayerOne;
  LevelChecker IsLevel40{40};
  LevelChecker IsLevel50{50};

  if (IsLevel40(PlayerOne)) {  
    std::cout << "Player is level 40 or above";
  }

  if (!IsLevel50(PlayerOne)) {
    std::cout << "\nBut not level 50 or above";
  }
}
Player is level 40 or above
But not level 50 or above

In this lesson, we’ll cover a more direct and flexible way of implementing partial application, using std::bind.

Fold Expression

An introduction to C++17 fold expressions, which allow us to work more efficiently with parameter packs
Abstract art representing computer programming
Ryan McCombe
Updated
Published

C++17 introduced fold expressions, which provide a shortened syntax to implement simple recursive algorithms that act on a parameter pack. A fold expression looks like this:

(Args + ...)

It has four components:

  • A set of parenthesis, ( and )
  • An expression involving a parameter pack. In this example, we’ve assumed our parameter pack is called Args
  • An operator - in this example, we’ve used +
  • A set of ellipses - ...

We’ll delve into the specific behavior of parameter packs throughout this lesson.

Class Templates

Learn how templates can be used to create multiple classes from a single blueprint
Illustration representing computer hardware
Ryan McCombe
Updated
Published

In the previous section, we introduced the std::pair type, which allows us to create containers for storing two pieces of data, of any type.

We provide the two data types we will need to store within chevrons, < and >:

std::pair<int, float> MyPair;

We can then access the values stored in those slots using class variables called first and second:

#include <utility>
#include <iostream>

int main() {
  std::pair<int, float> MyPair{42, 9.8f};

  std::cout << "First " << MyPair.first
    << "\nSecond " << MyPair.second;
}
First: 42
Second: 9.8

std::pair is an example of a template and, in this lesson, we’ll see how we can create our own templates to give similar flexibility.

Forward Declarations

Understand what function prototypes are, and learn how we can use them to let us order our code any way we want.
3D art showing a technician character
Ryan McCombe
Updated
Published

So far, we've been working under the restrictions that functions must be declared before they are used. For example, we've been unable to create code like shown below:

int main() {
  // Add is not defined yet
  Add(1, 2);
}

int Add(int x, int y) {
  return x + y;
}
Error: 'Add': identifier not found

Because the compiler reads our files top-to-bottom, when it reaches line 3, it encounters a call to a function that it’s not aware of.

The easy solution we've been using has been to move Add above main. However, we may not want to do this for stylistic reasons.

Worse, not all problems in this category can be solved by just moving functions around.

The Modulus Operator (%)

Learn how we can use the modulus operator to get the remainder of integer division, and some common use cases.
3D art showing a technician character
Ryan McCombe
Updated
Published

In this short lesson, we'll explore how the modulus operator helps in obtaining the remainder after division. This has many applications and is particularly useful when we’re solving problems using loops.

We can imagine that the answer to a division question like 5/35 / 3 might be 11, with 22 left over. This is an example of modular arithmetic.

Quotients and Remainders

When performing division using modular arithmetic, we get two results:

  • The quotient, which is 11 in this case
  • The remainder, which is 22 in this case

Fizz Buzz

Put everything we've learned in this chapter to the test by creating a C++ version of the Fizz Buzz game.
3D art showing a teacher
Ryan McCombe
Updated
Published

FizzBuzz is a word game used to teach young school children about division. The students sit in a circle and take turns counting, one number each.

Any number that is divisible by 3 is replaced with the word "Fizz"; numbers divisible by 5 are replaced with "Buzz", and numbers divisible by 15 are replaced with "FizzBuzz".

The sequence looks like this:

1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz,
11, Fizz, 13, 14, FizzBuzz, 16, 17...

This game, and variants of it, gained popularity within the programming community.

This is because implementing a program that can "solve" FizzBuzz requires a solid foundation in programming. It uses variables, operators, loops, conditional statements, and functions.

It is a useful milestone to ensure we understand all these basic principles. For this reason, candidates applying to programming jobs are sometimes asked to implement FizzBuzz in their interviews.

Tick Rate and Time Deltas

Learn how to create smooth, time-aware game loops that behave consistently across different hardware configurations
Abstract art representing computer programming
Ryan McCombe
Published

In the previous lesson, we introduced the concept of ticking and tick functions, which allow our game objects to update on every iteration of our application loop.

However, we should note that when we’re implementing logic in a Tick() function, we don’t know how quickly our objects will tick. That is, we do not know how much time has passed since the previous invocation of that object’s Tick() function.

// Goblin.h
#pragma once
#include "GameObject.h"

class Goblin : public GameObject {
 public:
  int xPosition;

  void Tick() override {
    // This object moves by one pixel per
    // invocation of Tick(), but how frequently
    // is Tick() invoked?
    xPosition += 1;
  }
};

As we add more complexity to our tick functions or more ticking objects, our game will need to perform more work on each iteration of our application loop. As such, it will iterate less frequently, meaning Tick() is invoked less frequently, meaning our object will move slower.

On the other hand, if we perform optimizations or our user has a more powerful computer, our loop can iterate faster, causing our objects to move faster.

To address this inconsistency, we typically want to define properties like movement speed in terms of real-world units of time, such as seconds or milliseconds. Let’s learn how to do this.

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:

  • 59 Lessons
  • Over 200 Quiz Questions
  • 95% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Capstone Project
3D art representing computer programming

Building Minesweeper with C++ and SDL2

Apply what we learned to build an interactive, portfolio-ready capstone project using C++ and the SDL2 library

Free, unlimited access

This course includes:

  • 37 Lessons
  • 100+ Code Samples
  • 92% 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:

  • 125 Lessons
  • 550+ Code Samples
  • 96% Positive Reviews
  • Regularly Updated
  • Help and FAQ
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