# Delving into C++

*2025-05-11*

> Not as difficult as I thought


As [mentioned previously]({{< relref "posts/2025/learning-unreal-engine" >}}), a prerequisite of the [CG Spectrum](https://www.cgspectrum.com) [Game Programming Foundations](https://www.cgspectrum.com/courses/game-programming-foundations) course is a basic understanding of the [C++ programming language](https://en.wikipedia.org/wiki/C%2B%2B).

My programming experience has mostly been with higher-level languages. I started with [Visual Basic](https://en.wikipedia.org/wiki/Visual_Basic_(classic)) before moving on to [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) and then [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)).

Of those, I've always found C# particularly intuitive, but I've also wanted to learn C++ for a long time.

Since I already had a solid understanding of the core principles, I saw little value in taking extensive notes on concepts I was already familiar with, and instead committed code to:

[sawnoff-studios/game-programming-foundations](https://github.com/sawnoff-studios/game-programming-foundations)

This also gives me a practical reference to return to, while letting me track my progress through the course.

## Topics

The topics studied over those 12 weeks were:

- Game Programming Concepts
- Variables and Operators
- Conditionals
- Loops
- Functions
- Classes and Objects
- Pointers, References & Dynamic Memory
- Arrays
- Inheritance & Polymorphism
- Templates
- Game Loop
- Putting It All Together

This was followed by using the [**PlayBuffer** library](https://github.com/sumo-digital-academy/playbuffer) to practise implementing the concepts learned, committed to [sawnoff-studios/playbuffer](https://github.com/sawnoff-studios/playbuffer).

Through this I gained a deeper understanding of how to use C++ to create games, with [cppreference.com](https://cppreference.com) and [GeeksforGeeks](https://www.geeksforgeeks.org/cpp/c-plus-plus/) proving invaluable.

## Differences

While primitive types such as `int`, `float` and `bool` are similar to their C# counterparts, there are key differences in the standard library data structures – for me mostly in the *naming* rather than the implementation:

| C++ | C# equivalent | Description |
|---|---|---|
| `std::vector` | `List<T>` | Dynamic, resizable array |
| `std::list` | `LinkedList<T>` | Doubly linked list |
| `std::string` | `String` | String class |
| `std::map` | `Dictionary<TKey, TValue>` | Stores key/value pairs |
| `std::deque` | *(no direct equivalent)* | Double-ended queue |

## References vs Pointers

One of the main differences between references and pointers in C++ is how they handle nullability, reassignment, syntax, memory management, and flexibility.

In managed languages such as C# and Java, garbage collection handles memory automatically; in C++, memory management is manual and requires the `new` and `delete` operators.

| Feature | References | Pointers |
|---|---|---|
| Nullability | Cannot be null | Can be null (`nullptr`) |
| Reassignment | Cannot be reassigned | Can be reassigned |
| Syntax | Simple, no dereferencing | Requires `*` or `->` |
| Memory management | No manual management | Requires `new`/`delete` for heap data |
| Flexibility | Tied to one object for its lifetime | Can point to different objects |

## Recap Thoughts

### Code is spread out a lot across files.

Coming from higher-level languages, it felt like a pain switching between the `.h` file to define class members and the `.cpp` file to implement them. I started seeing `.h` files as the '[interface](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/interface)' to a class, which is different to what I'm used to.

It's a bit of a hassle, but a necessary evil – otherwise, I found C++ remarkably similar to C#.

### Alternate constructor syntax is weird.

In C#, constructors look like this:

```csharp
public class Person
{
    private string _name;
    private int _age;

    public Person(string name, int age)
    {
        _name = name;
        _age = age;
    }
}
```

Whereas C++ initialises members in an initialiser list - with the members defined in the `.h` file, then assigned via what looks like a method call in the `.cpp`:

```cpp
// Person.h
class Person
{
    std::string m_name;
    int m_age;

public:
    Person();
    Person(std::string name, int age);
};
```

```cpp
// Person.cpp
#include "Person.h"

Person::Person()
    : m_name("Unnamed")
    , m_age(0)
{
}

Person::Person(std::string name, int age)
    : m_name(name)
    , m_age(age)
{
}
```

### Friend is a scary concept.

The `friend` keyword grants a class access to another class's private and protected members, breaking encapsulation.

In the course example, two classes were defined - `Spiderman` and `Venom` - with `Venom` declared a friend of `Spiderman`, allowing `Venom::AccessSpidermanHealth()` to modify `Spiderman`'s health without inheritance.

I found it a bit of a scary concept – no such thing exists in C# without [compiler workarounds](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.internalsvisibletoattribute?view=net-10.0).

```cpp
// Spiderman.h
#pragma once
#include <string>

class Venom; // Forward declaration

class Spiderman
{
    friend class Venom;

public:
    Spiderman();
    Spiderman(int inHealth);

private:
    std::string name;
    int health;
};
```

```cpp
// Venom.h
#pragma once
#include "Spiderman.h"

class Venom
{
public:
    Venom();
    Venom(int inHealth);

    void AccessSpidermanHealth();

private:
    Spiderman spiderman;
};
```

```cpp
// Venom.cpp
#include <iostream>
#include "Venom.h"

Venom::Venom() : Venom(0)
{
}

Venom::Venom(int inHealth)
{
    spiderman.health = inHealth;  // Legal only because of the friend declaration
}

void Venom::AccessSpidermanHealth()
{
    std::cout << "Accessing Spiderman health " << spiderman.health << '\n';
}
```

### Forward declarations are interesting.

In higher-level languages, you define a class and it can instantly be referenced elsewhere.

In C++, [forward declarations](https://www.geeksforgeeks.org/cpp/what-are-forward-declarations-in-c/) let you declare a type's existence 'ahead of time' for the compiler:

```cpp
// Player.h
class Enemy; // Forward declaration

class Player
{
public:
    static void PlayerTurn(Player& player, std::vector<Enemy>& enemies);
    static void PlayerAttack(Player& player, Enemy& enemy);
};
```

```cpp
// Enemy.h
#include "Player.h"

class Enemy
{
public:
    static void EnemyTurn(Player& player, Enemy& enemy);
    static void EnemyAttack(Player& player, Enemy& enemy);
};
```

Here, `Player.h` references `Enemy`, but adding `#include "Enemy.h"` to `Player.h` would create a circular reference – each header including the other, a chicken-and-egg situation. Forward-declaring `Enemy` in `Player.h` and including the full header only where needed breaks the cycle.

The second benefit is compile times: an `#include` in a `.h` file pulls in everything from that file, *including its own includes* - pages and pages of code that need compiling. Forward declarations only reference what's required.

### Operator overloading can be useful.

Another scary-seeming concept: overloading existing operators such as `+`, `==` and `=` for custom types. It makes for intuitive, readable code, but can cause confusion if misused:

```cpp
#pragma once

class Position
{
public:
    Position();
    Position(float inX, float inY);
    ~Position();

    Position operator+(const Position& other) const
    {
        return Position(X + other.X, Y + other.Y);
    }

    bool operator==(const Position& other) const
    {
        return ((X == other.X) && (Y == other.Y));
    }

    Position& operator=(const Position& other)
    {
        X = other.X;
        Y = other.Y;
        return *this;
    }

private:
    float X;
    float Y;
};
```

[Three overloaded operators](https://github.com/sawnoff-studios/game-programming-foundations/tree/main/Lesson09/Task1) - `+`, `==` and `=` - allowing Positions to be added, compared, and assigned:

```cpp
Position pos1(1.0f, 2.0f);
Position pos2(3.0f, 4.0f);

Position pos3 = pos1 + pos2;      // pos3.X = 4.0f, pos3.Y = 6.0f
bool areEqual = (pos1 == pos2);   // false
pos1 = pos2;                      // pos1.X = 3.0f, pos1.Y = 4.0f
```

### Pointers aren't that scary.

[Pointers](https://www.geeksforgeeks.org/cpp/cpp-pointers/) aren't really a concept in higher-level languages, but they're fundamental to C++. I'd always been a bit scared of them – I'd heard they can have unintended consequences – but they're simple once you get the hang of them.

In the [course example](https://github.com/sawnoff-studios/game-programming-foundations/tree/main/Lesson06/Task2), a `Car` struct is allocated on the heap via a pointer, and its members accessed through the dereference operator (`->`):

```cpp
#include <iostream>
using namespace std;

int main()
{
    struct Car
    {
        string make;
        string model;
        int year;
    };

    Car* car = new Car();

    cout << "Enter the car's make\n";
    cin >> car->make;

    cout << "Enter the car's model\n";
    cin >> car->model;

    cout << "Enter the car's year\n";
    cin >> car->year;

    cout << "You entered " << car->year << " " << car->make << " " << car->model;

    delete car;  // Don't leak!
    return 0;
}
```

### References are interesting.

Following on from pointers, [references](https://www.geeksforgeeks.org/cpp/references-in-cpp/) were equally interesting – they act as an alias for an existing variable:

```cpp
#include <iostream>
using namespace std;

int main()
{
    int x = 10;

    int& ref = x;  // ref is a reference (alias) to x

    cout << ref << endl;  // Prints 10

    ref = 22;             // Writing through ref modifies x itself

    cout << ref << endl;  // Prints 22
    cout << x << endl;    // Prints 22 - x and ref are the same object

    return 0;
}
```

## Certificate

After three months of study, I officially passed this module and received my certificate on 26th June 2025.

Many thanks to [Cameron Cintron](https://www.linkedin.com/in/ccgamedesigner/) for your support and encouragement throughout this part of my journey!

Onwards towards learning Unreal Engine!

<div style="text-align: center;">
    <a href="https://www.credential.net/ee6d04ae-b821-4c01-8b36-be4422076b23" target="_blank">
        <img src="certificate.png" alt="Game Programming Essentials certificate">
    </a>
</div>
