Skip to main content

Classes

Ring Buffer Series Part 6 — Storage and Lifetimes

class We closed part 5 by promising to tackle move semantics, but there is foundational work that needs to be done before that can happen. Move semantics will come in the future, but in this post we need to make sure our storage is capable of supporting it and we will have to rebuild one of the components we made in part 2, so buckle up because this will be a long one.

Ring Buffer Series Part 5 — const_iterator

class Previously we expanded our RingBuffer by implementing its own iterator class along with iterator traits. This allowed us to make it work with range-based for loops and most algorithms in the C++ Standard Library, but it still has a limitation.

void print_contents(const RingBuffer<int, 8>& buf)
{
    for(auto x : buf)
    {
        std::cout << x << ' ';
    }
}

The compiler will not allow it. Our begin() and end() are not const qualified, which means they can’t be called on a const object. In this episode we will fix this by introducing const_iterator, an iterator that promises not to modify the elements it visits.

Ring Buffer Series Part 4 — Iterators: Walking the Ring

class In Part 3 we expanded on the original buffer and it now supports any type and any size. Our RingBuffer almost behaves like any of the STL types, such as std::vector and I say almost. Consider the following code:

int main()
{
    RingBuffer<int, 10> my_buffer;
    for (int i = 0; i < 10; ++i)
    {
        my_buffer.push_back(i);
    }

    for (auto x : my_buffer)       // This line produces an error.
    {
        std::cout << x << ' ';
    }
}

This code should work, but if we actually try to run it we will get a compiler error.

Ring Buffer Series Part 3 — Templates: One Buffer, Any Type, Any Size

class In Part 2 we built a buffer that works, however it is stuck with unsigned int and size 8, but what if we wanted to use it with std::string or custom types like game events, or only store the last 4 frames? Do we write a buffer per class? We could, but that would be a nightmare, wouldn’t it?

Meet Templates

In C++, templates are a powerful mechanism for generating code. A template is a blueprint that the compiler uses to generate actual code. Think about it this way, a class is a blueprint for a thing (a type of thing), templates are blueprints for classes.

Ring Buffer Series Part 2 - Implementation

class In Part 1 we covered the fundamental building blocks: classes, functions, constructors and how to organize code into header and implementation files. We created a simple Person class to illustrate these concepts and now it is time to apply what we learned to our main project: The RingBuffer. Remember, our ring buffer needs to do a few key things: store elements, track where to add the next one, and know when it’s full. Let’s begin by creating a class.

Ring Buffer Series Part 1 - Classes and Functions - The Building Blocks

class Hello! If you recall from the previous series, we built a program that handled text input, stored numbers into a vector and performed calculations. However there were some concepts in there that we used, but that I didn’t really explain. I am referring to iterators. In this new series I aim to go over what they are, how they work and how to use them, so get ready because it will be a bumpy ride and as usual, we will have to build our way there because fundamentals are always important.