Category Archives: C++11

Posts about the new C++11 standard. Will also cover some parts from the other C++ standard and some from the brand new C++14

[ C++11 – Part 4 ] STL-Iterators

Standard Template Library


A major part of C++ is the Standard Template Library ( STL ). It is quite large and it contains both containers ( like vector, stack and maps ) with a lot of functionality for using these. In this post, we’ll look at one part of the STL, iterator, and in the following post we’ll look at other parts of STL like the algorithms library

Iterators


Iterators can be looked at like pointers. They reference an item in a data structure( including string ). They can also be used with streams. The iterators enables us to iterate through them using various operations like ++.

But we need different types of iterators because data structures can often be iterated in different ways. Some ways are efficient on some containers while they might be inefficient or even impossible on other containers.

Let’s take a look at the different type of iterators.



Here’s a simple overview :

Iterators overview


The properties of the various iterators here are the bare minimum of the “pure” version of the iterators. Some implementations might support more operations.

Note that forward iterator, bidirectional iterator and random access iterator does not implement output iterators. This means that they can’t, by definition, write to the object they refer to. We’ll get back to this later.

Let’s start by looking at the first type of iterator, output iterator.

Output iterator


As mentioned earlier, output iterator is a very limited type of iterator it is also the only iterator that can write to the object.

You can’t go back with an output iterator, and you can’t iterate over the same range twice. And there is no guarantee that you can write to the same position twice without incrementing the operator. And you can’t compare two output iteratrs either. What you’re basically doing is writing into a “black hole”; you’re just writing and you can’t see what you have written.

This might seem very constrictive, there’s very little we can do. But these rules only apply in some cases, like when writing to streams, which we’ll look at later. You can look at the iterators that follows everything described above as pure output iterators

Most iterators, though implement output iterators but also has other traits that enables more functionality. We’ll look at these later.

A simple example


This is a very simple example of the intended usage for output iterators :

Or, in other words :

  • Write
  • Move forward
  • Write
  • Move forward

A bit more complex example


In C++ you have streams, which allows you to to either write or read from them using the >> and << operators. Examples of this is cout ( write ) cin ( read ). This makes cout output operators ( because they output to the terminal. )

cout is of the type ostream. You also have an iterator to this type, called ostream_iterator that can be set to an ostream Writing to this iterator writes to the ostream it’s an iterator to.

Using this knowledge, we can create an iterator to cout, this enables us to write to the terminal using an iterator

Output :

11
44
33

The ostream_iterators are output iterators. Using cout like this shows how output iterators works ; you can only write and the writing has to be sequential. You can newer go back. Once you’ve written something, you can’t “go back” and write something in the position before what you just wrote.

Input iterator


The counterpart of output iterators is input iterators. But where output iterators can only write, input iterators can read but there is also a small changes in the restrictions :

  • You can compare two iterators
    • Comparing two  iterators is not guaranteed to work unless at least one of them is past the end ( like std::end )
  • Since you can read, you can also use the -> operator to access member variables

    A simple example


    The following example shows the essential use of an input iterator :

    Or, in other words :

    • Read
    • Move forward
    • Read
    • Move forward

    A more complex example


    In the previous example, we saw that ostream_iterators are output iteratorss. Which means we can use them to write to cout. Similar to this, we have istream_iterators that are input operators. And where we can use ostream_iterators with cout, we can use istream_iterators with cin which reads input.

    Here too we have to work consecutively, we can’t go back or skip ahead, we can read input in a similar to when we wrote to cout

    Example input :

    3
    2
    6
    f

    Output :

    Write 3
    You wrote 3
    2
    Write 2
    You wrote 2
    6
    Write 6
    You wrote 6
    f

    Since we’ve specified int as the template argument of the input_iterator, the input_iterator ( intReader ) will become the same as invalid, which in C++ means the iterator will point to the element past the end element. This is the same as readerEnd and the loop will terminate.

    Forward iterator


    If you take a look at the iterator overview above, you’ll see that the forward iterator implements input iterator. This means a forward iterator can do anything an output iterator can do.

    Forward vs input operator


    A forward iterator has a few extra features that input iterators don’t have. These are :

    Equality check


    Two forward iterators are guaranteed to compare as equal if they refer to the same element

    • An input iterator can, as we saw above, be compared to another output iterator, but the operation is only guaranteed to be true  if one of them is past the end of the container

    Example :

    The compare operation ( it1 == it2 ) is not guaranteed to be true for  output iterators or input iterators, but it is for forward iterators

    Forward iteration


    A forward iterator can also iterate forward as many times as you like before reading

    • With  output iterators or input iterators we would have to read or write in between each time we iterate forward.

    Example :

    If we had used an output iterator or an input iterator to do the multiple iterations would have caused the iterators to become invalid.

    Iteration over same range


    Finally, a forward iterator can iterate over the same range twice.

    • output iterators or input iterators are intended to only iterate over the same range once ( single-pass ) but are intended to be able to do this ( multi-pass )

    Example :

    Here we’ve effectively moved back and continued moving forward, which again would not be possible with code>output iterators or input iterators.
    As you can see, using  forward iterators is in many ways more convenient than using output iterators or input iterators, but some object only has very few operations, like the streams we looked at earlier.

    Luckily, most ( if not all ) structures in the C++11 supports at least the functionality of forward iterators. Most of them provide iterators that has more properties, but this time we’ll look at a structure that only provides forward iterators

    Forward list


    A linked list is a container that works a bit different from the array-like containers. Basically, each element has a pointer to the next element. So that all the elements are chained together using pointers. If you want to go from one element to another, you use the next pointer. This can mean a lot of operations if the list is very large.

    The objects will not be one contiguous piece of memory like arrays are. This means there are no quick ways to go from the first to the last element. So if we wanted to go from Node 1 to Node 2 in the above illustration, we would have to go via Node 3. And if we wanted to go back from Node 3 to Node 1 we would have a problem. There is no pointer that goes back in a forward list. If you want to get to a previous node, you would need a pointer to an earlier element. The forard_list itself keeps a pointer to the first element in order to be able to access all elements.

    A container in like this didn’t exist in C++ until C++11 which has the container forward list.

    Iterating forward lists


    The forward list is a great way of showing how the forward iterators works. The forward list can only be iterated forward and the forward iterator can only iterate forwards.

    Let’s look at an example :

    We are now at the fifth element ( 5 ), but say we want to print the previous element ( 0 )? We need to go back to the begin element and increment like above.

    Output :

    43
    63
    11
    0
    5
    0

    Forward iterators and output iterator


    • Per definition, forward iterators  does not include the properties of output iterators. 
      • Most implementations of forward iterators does however support assignment like output iterators. These iterator are called mutable forward iterators

    Bidirectional iterator


    The bidirectional iterator is very similar to forward iterator. The only different is that it also supports backwards iteration. And that’s all the difference between code>forward iterator and bidirectional iterator.

    Linked list


    In the forward iterator section we looked at singly linked lists which has a pointer to the next element. But most linked lists also has a pointer to the previous element.These are called doubly linked lists or simply just linked list.

    The container type doubly linked lists are identical to singly linked lists, with the one exception that each Node now has a pointer to the previous Node too.

    The prev pointer enables us to iterate backwards, so now we need an iterator that can iterate backwards and forwards. This is where the bidirectional iterator comes in.

    An example


    The following example is the similar to the example for forward list but this time we solve the last problem in a different way.

    We are now at the fifth element, but say we wanted to go back to the previous element? Since doubly linked lists support bidirectional iterators, we can use -- to iterate back.

    -it;

    Output :

    43
    63
    11
    0
    5
    0

    As you can see, bidirectional iterators can iterate back and forth without problems. Now let’s look at the final iterator, random access iterator.

    Random access iterator


    The final iterator is also the one with the most features. It can be used like a pointer. In fact, some implementations of STL uses pointers as random access iterators.

    Here’s a list of the features of a random access iterator

    • All the features of bidirectional itearator
    • Random access
      • Access items by [] operator
        • it[n] returns the value of the position it + n
        • it[n] is the same as *( it + n )
    • Iterator arithmetics
      • This means you can add or subtract integer values and iterators
        • it += n moves it forward n steps
        • it -= n moves it backward n steps
        • it + n returns an iterator to the element n steps after it
        • n - it returns an iterator to the element n steps before it
        • it - it2 returns the distance between it and it2
    • Iterator comparison
      • This means you can check which if one iterator is before another iterator
        • it1 < it2 returns true if it1 is before it2
        • it1 > it2 returns true if it1 is after it2
        • it1 >= it2 returns true if it1 is not before it2
        • it1 >= it2 returns true if it1 is not after it2
        • not it1 < it2 

    Array-like containers


    Array like containers are all containers that are organized as a continuous piece of memory. This means you can predict where the next item is, since it the next item will always be the previous item + the size of each item. Using this knowledge, it’s easy to jump forward or backwards. An example of these containers is vector, which I covered in a previous part.

    The above example shows how any array-like container ( vector, array, queue, deque, … ) is laid out in memory. Everything is in one continuous block which means we always know where the next element is.

    An example


    The following example shows usage of random access iterators:

    Conclusion

    There are several types of iterators in C++. Especially random-acces iterators can be particularly useful. We will see more of this in the next post. The next part will also introduce a few new iterators, but they are all variations of the iterators in this post.


    Feel free to comment if you have anything to say or ask questions if anything is unclear. I always appreciate getting comments.

    You can also email me : olevegard@headerphile.com
    Share

    [ C++11 – Part 3 ] Smart pointers

    Memory in C++


    One of the major parts of C++11 is the new smart pointers. But why do we need them, and why should you steer away from the old style pointers?

    This post is intended both as an introduction, and a reference guide to the smart pointers found in C++11. It will cover what they are, how to use them and how they work.

    Memory allocation in C++


    C++ supports dynamic memory allocation ( new / delete ). It’s a way of creating a object whenever you need it. The object will live until you call delete on it. Otherwise it won’t be deleted, not even when it goes out of scope. And if you don’t delete it, none will, which in turns causes memory leaks. It might also cause undefined behavior ( which means anything can happen ) if, for instance, you delete something and try to use it afterwards.

    Smart pointers will help you with these issues and make your code cleaner and better.

    Smart pointers


    Smart pointers are like regular pointers, but they provide extra functionality such as automatic checks or other safety mechanisms. C++11 introduces three smart pointer types :

    • unique_ptr
      • Only one unique_ptr can point to the object at the time
    • shared_ptr
      • Several shared_ptrs can point to the object at a time.
      • Object is released when no shared_ptrs point to the object
    • weak_ptr
      • Non-owning, needs to be converted into an shared_ptr to use the object it points to

    Using smart pointers


    Once you have created the smart pointer, you can use it as a regular pointer :

    • ->
    • *
    • !
    • ==
    • ...

    All of the above operations are supported for the smart pointers in C++11. This is not true for weak_ptr, but we’ll get to that later.

    You can also use them in ifs like this :

    It will enter the if as long as the smart pointer is initialized and is managing a valid object ( meaning it’s not a NULL pointer )

    We’ll now take an in-depth look at the smart pointers, one at the time.

    unique_ptr


    An unique_ptr is the sole owner of an object that it points to. Two unique_ptrs can also swap objects, but they can never manage the same object. And as with all smart pointers, it takes care of deleting the object. 

    Initialization and allocation


    There are two ways of doing this, regular constructor or make_unique

    constructor


    The constructor is pretty straight forwards. You just set the template arguments ( in this case Foo ) and pass an allocated ( new‘ed ) object :

    This is pretty straight forwards ; template parameter is the type and you supply an allocated ( new‘ed ) object.

    make_unique


    The second alternative is using a function named make_unique, this is in most cases better, because it constructs the object and it helps prevent errors. It also follows the naming convention ofshared_ptr which can be constructed in the same way with the make_shared method.

    This is how to use make_unique :

    What make_unique does is that it creates a new unique_ptr that manages a new object of the template type ( Foo in our case. ) It takes the arguments of the make_unique function itself and passes it to the constructor of the new Foo. Then the function returns the unique_ptr it created and the =operator assigns it to the unique_ptr we declared ( p2 )

    This function requires C++14, it should have been included in C++11, a simple oversight lead to it not being included in the standard. But don’t worry, it’s easy to get this to compile:

    • On Linux / Mac
      • Change -std=c++11 to -std=c++1y in your compile command
    • On Windows
      • Newer versions VisualStudio should support this without you having to do anything.

    If neither of the above works, you can copy-paste this :

    Destruction and deallocation


    Since the unique_ptr is a smart pointer, it handles deallocation automatically. In general, this means that the unique_ptr calls delete on the object it holds. This happens when :

    • The unique_ptr is being destroyed.
      • Happens when the unique_ptr goes out of scope.
    • You set the unique_ptr to point to something else
      • More on this below.

    Releasing the object


    Releasing the object means that the unique_ptr stops managing the object. This means you can let a regular pointer “take over” the object the unique_ptr was managing. So when the unique_ptr goes out of scope or is destroyed in any way, the pointer object it was managing wont be affected.

    Here’s an example :

    • fooUPtr now manages pFoo1
    • pFoo1 is unchanged

    • fooUPtr no longer manages the object pFoo1 points to
    • pFoo2 now points to the same object as pFoo1

    But now pFoo1/pFoo2 needs to be deleted. Since they both point to the same object, we just need to delete one of them :

    Changing the object being pointed to / reassignment


    Changing what the unique_ptr points to is quite easy. It can be done in two ways :

    These are used in a similar work

    And

    Both of these properly deallocates the original object managed by foo1, calling its destructor in the process. Then the new object returned by new is assigned to foo1 and foo1 now manages it just like it did with the previous object.

    Transferring ownership


    You can’t set two unique_ptrs to manage the same object, but you can transfer ownership from one unique_ptr to another. And you can swap the managed object of two unique_ptrs.

    Swapping owenership


    Swapping ownership can be done in two ways ; a member function, or the std::swap() function.

    Member function

    The member function is very straight forwards :

    std::swap

    std::swap() is a very simple, but also very useful algorithm defined in the algorithm header ( until C++11 and utility since C++11 ). It basically swaps two objects of whatever type you pass as arguments. It can be two ints, two std::strings or two objects of a class/struct or anything else you want.

    The version used for unique_ptrs is just an overload of this that uses the above swap( std::unique_ptr ) member function function internally. Here’s how to use it :

    So in reality, the member function and swap() are identical. The result of both of these are as you would expect :

    • foo1 now manages foo2
    • foo2 now managesfoo1

    Reseting


    You can use the reset() to reset the unique_ptr This means that we change what pointer the unique_ptr manages, deleting the old one. This method can only be used with raw pointers, not smart pointers.

    Example :

    What this does

    • Crates a new uniqe_ptr that manages a new Foo object
    • Deletes the old managed Foo object and replaces it with a new one

    Transfering owenership


    You can use the = operator to transfer ownership :

    This takes the pointer from foo2 and gives it to foo1. This means that :

    • foo2 no longer handles any object ( like calling )
      • This is because only one unique_ptr can manage an object at a time
    • The object that foo1 was holding is deleted
      • Because foo1 is going to be managing foo2

    This is the same as doing :

    Note that this is not the same as swapping two unique_ptr

    If we swap, the result would be :

    • foo1 manages foo2 
    • foo2 manages foo1

    In this case the result is.

    • foo1 manages foo2 
    • foo2 doesn’t manage any object

    Destroying the object


    When you want to destroy the object the unique_ptr manages, there are two ways you can do it:

    • Destructor
      • This simply means letting the unique_ptr go out of scope
    • The reset() method
      • You can use this with either a NULL pointer or another pointer, the managed object will get deleted in both cases

    The bool operator


    The bool operator dictates what happens when used in a boolean expression like if () . It will return true if the unique_ptr manages an object. If not, it’ll return false. In other words ; if, and only if, you can use it, it’ll return true, so this is exactly the same as you do when you’re checking if a pointer is NULL or nullptr

    The other operators


    The other operators works just like regular pointers, so I won’t discuss them here.

    shared_ptr


    shared_ptr is, as the name implies, a smart pointer that allows sharing. This means you can have several shared_ptrs that point to the same object. This is not permitted by unique_ptr as we saw in the previous section.

    Implementation


    The shared_ptr is a bit more complex than unique_ptr. This is because a shared_ptr needs to keep track of how many other shared_ptrs are managing this object, But for unique_ptrs there will always be only one pointer managing the same resource, so there is no need to keep track of the number of other unique_ptrs that are managing this object ( because it’s always just one! )

    In order to keep track of this information, shared_ptr keeps a pointer to a structure called a control block. This structure has three member variables :

    •  shared_ptr reference count
      • How many shared_ptrs are managing to the object
    • weak_ptr reference count
      • How many weak_ptrs are referring to this object
        • More on  weak_ptrs later
    • A pointer to the object the shared_ptr manages

    The shared_ptr also keeps a pointer to the object it manages. And this is where it gets a little complicated, because this pointer is closely related to the one in the control block. But why? The reason for this is a bit complicated and it has to do with the two ways of creating a shared_ptr, make_shared and constructor. I will discuss this in the next section :

    Initialization


    When it comes to unique_ptr, the difference between using make_unique and the regular constructor is slight ( that doesn’t mean you shouldn’t use make_unique as often as you can! ) But in a shared_ptr things are different.

    As stated above, a shared_ptr has two elements : a control block and a pointer to the object it manages. Both of these needs to be allocated, but before we get into that, let’s look at how we can create a shared_ptr :

    Or

    Using constructor


    In the first example, we first allocate Foo using new before pass it to the shared_ptr constructor. This means that the shared_ptr has no control over the allocation of Foo so all it can do is to create the control block and have it point to Foo. The figure below will show the procedure for when you create a shared_ptr using constructor :

    Foo and ControlBlock allocated in two steps

    As you can see, the control block and the Foo needs to be allocated in two steps. First the object, then the control bloc.

    Using make_shared


    But if we let make_shared handle the allocation of Foo, it can allocate both the control block and Foo in one go. It’ll look something like this :

    Foo is now part of the FooControlBlock

    So make_shared creates the object and the control block together in one operation. This makes the operation faster than creating them in two step, but it requires them to be one object, so here Foo is part of the control block itself.
    make_shared is available in C++11 so you can use it without enabling C++14

    When not to use make_shared?


    There are two cases when you can’t use make_shared :

    • If you are using a pointer that’s already created somewhere else
      • Using make_shared means the object would be re-allocated
      • Pass the pointer in the constructor instead ( where we passed new Foo() in the example above )
    • If you don’t want to use the default delete
      • You can’t specify a custom deleter using make_shared
      • This is a bit complicated, so I won’t go into details

    Destruction and deallocation


    The destructor for shared_ptr is also a bit different from unique_ptr because an unique_ptr will always be the sole manager of an object ( not other unique_ptr or shared_ptrswill be managing it. ) This means it’s always safe to delete, so that’s what the unique_ptr will do.

    But when it comes to shared_ptrs, we can’t do that before we make sure that no other shared_ptrs are managing it. So what we do is that we look on the control block and how many shared_ptrs are managing it. If this is 0, we are the last owner and we can safetely delete it.

    The weak_ptr reference count it not checked at this point. I’ll get into why in the next section that discusses weak_ptr and how the relate to shared_ptrs.

    Changing the object being pointed to / reassignment


    Similar to unique_ptrs but here we need to do some extra work. There’s two different cases for this ; setting the shared_ptr to be the same as another shared_ptr and setting the shared_ptr to manage a new pointer.

    In both of these cases, it will decrement the shared_ptr reference count in the control block. And if this count reaches 0 it will delete the object being pointed to ( but not necessarily the control block, more on this later. )

    Assigning to a different shared_ptr


    Assigning a shared_ptr to a different shared_ptr is done using the =operator.

    Here’s a simple example

    Result

    • The original ptr1‘s shared_ptr count is now 0, and the object it manages will be deleted
    • ptr1 and ptr2 will now both manage the same object as the original ptr2 with a shared_ptr count of 2

    Assigning shared_ptr to a new object


    Assigning a shared_ptr to a new object/pointer is done using the reset() function :

    Here’s a simple example

    Result

    • The shared_ptr reference count for sharedPtr is decremented as if we were calling the destructor.
      • The Foo object sharedPtr was originally manging may get deleted
    • sharedPtr now manages the object rawPtr points to.

    As you can see from the examples, you use opeator= for reassigning to another shared_ptr but reset() for reassigning to a different raw pointer. You can’t use them the other way around. This can help prevent bugs by giving an error if the programmer uses the wrong versions.

    There is a way you can use operator= to assign to a new pointer;  using make_shared to create a new object :

    This works because make_shared creates and returns a fully constructed shared_ptr ( just like make_unique described above ) and the =operator assigns it just like in the example above.

    Swapping


    The syntax for swapping shared_ptrs is the exact same as for swapping two unique_ptrs :

    Member function :

    std::swap :

    This will, as you would expect, swap both the control block and pointer for both the shared_ptr. It needs to swap the control block since this is what keeps tracks of the number of references to the pointer so these needs to be consistent.

    The bool operator


    The bool operator dictates what happens when used in a boolean expression like if () . It will return true if the shared_ptr manages an object. If not, it’ll return false. In other words ; if, and only if, you can use it, it’ll return true, so this is exactly the same as you do when you’re checking if a pointer is NULL or nullptr

    This is exactly the same as for unique_ptr.

    The other operators


    The other operators, just like with unique_ptr, works just like regular pointers, so I won’t discuss them here.

    weak_ptr


    As mentioned in the introduction, weak_ptr doesn’t actually manage a pointer. It just holds a non-owning ( "weak" ) reference to an object that is managed by a shared_ptr. It also keeps a pointer to the control block ( the exact same as the one in the shared_ptr who manages the object. This means it has to be created from a shared_ptr so that it can get a pointer to the control block.

    wrak_ptr and the control block


    The control block, as we saw in the previous section, keeps a count of both shared_ptr and weak_ptr who’s using the object. We also saw that the object will get deleted if the count of shared_ptrs using the object is 0 regardless of how what the weak_ptrs count is. This is part of the point of weak_ptr; it is not supposed to keep objects alive except for in situations we explicitly tell it to.

    But even though the managed object will get deleted if the count of shared_ptrs is 0, the control block will remain intact. The control block will only be deleted if both the conut of shared_ptr and weak_ptr uses. This is because the weak_ptr uses the control block to check if the object is alive.

    Creating a weak_ptr


    There are two ways of creating a weak_ptr from a shared_ptr: constructor and =operator. This is very straight forwards :

    All of these will set up the pointer and the control block and increment weak count by 1.

    Creating a weak_ptr from a raw pointer won’t work simply because it isn’t designed to be managing a pointer by itself. And you can’t use them with unique_ptrs because unique_ptrs are supposed to be the sole owner.

    Reseting a weak_ptr


    The object a weak_ptr can be reset ( so that it no longer references any object ) using the destructor or the reset() function.

    Using a weak_ptr


    weak_ptr has the function lock(). What this function does is that it makes a shared_ptr of itself. This shared_ptr will work exactly as any other shared_ptrs maintaining the object. It will increase the shared_ptr count, so this shared_ptr will keep the object alive.

    If the object has been deleted, it will still return a shared_ptr. But this shared_ptr doesn’t point to anything, it’s essentially a nullptr. It will return false if you use it in a if or loop condition, just like a regular shared_ptr or unique_ptr that doesn’t manage an object.

    This function is the crucial part of the weak_ptr. It enables us to keep weak_ptrs that refers to object maintained by a shared_ptr without preventing it from being deleted and we can still use it safely when we want.

    So let’s look at an example :

    Usage 1


    Here everything works as intended. The weak_ptr refers to sharedPtr which has a valid object inside this scope.

    • lock() returns a shared_ptr that manages the same object as sharedPtr
    • The returned shared_ptr is valid so it enters the if
    • While in this if, the shared_ptr, fromWeakPtr1 keeps the object alive, even if all other shared_ptr should be destroyed in other threads in the meantime

    Usage 2


    Our shared_ptrs has gone out of scope ( both the original and the one we created from the weak_ptr and the object has been deleted. But the weak_ptr, weakPtr still exists as it was declared out of the scope. So we try to use it again :

    •  We create our shared_ptr from the weak_ptra
    • The shared is created, but since the original object was deleted, this is essentially a nullptr
    • The shared_ptr returns false and it doesn’t enter the if.

    Leaving the scope


    Finally we leave the scope and we delete weakPtr. Now the weak_ptr count will be 0 and the control block will be deleted ( shared_ptr count was already 0 )

    Releasing the object


    A weak_ptr can’t release the object because it doesn’t have control over it, and the object might be NULL. For this reason, weak_ptr does not have a release() function. The closest thing is the reset() function described above.

    Swapping


    The syntax for swapping weak_ptrs is the exact same as for swapping two shared_ptrs and code>unique_ptrs:

    std::weak_ptr< Foo >( new Foo ) foo2;
    std::weak_ptr< Foo >( new Foo ) foo2;

    Member function :

    foo1.swap( foo2 );

    std::swap :

    std::swap( foo1, foo2 );

    This will, as you would expect, swap both the control block and pointer for both the weak_ptrs. It needs to swap the control block since this is what keeps tracks of the number of references to the pointer so these needs to be consistent.

    Changing the object being pointed to / reassignment


    Similar to shared_ptrs but with a few differences :

    • Since we are not managing the object, we don’t need to worry about deleting it.
      • It might already have been deleted at this point, but this will not cause the opeartion to fail
    • Decrement count for weak_ptr, not shared_ptr
      • If weak_ptr count reaches 0 and the count for shared_ptr is also 0, we delete the control block
    • Now we can set the pointer to the object and control block
      • Both of these will already have been created by a shared_ptr

    You can create reassign a weak_ptr to both a shared_ptr and another weak_ptr


    Feel free to comment if you have anything to say or ask questions if anything is unclear. I always appreciate getting comments.

    You can also email me : olevegard@headerphile.com
    Share

    [ C++11 – Part 2 ] Timing

    std::chrono


    Today, we’ll learn how to use the chrono library. It’s used for timing functionality. It supports a variety of different operations and can be quite daunting in the beginning. The library contains several new types, but I’ll try to explain all of them shortly. But first a few practical tips that will make using std::chrono easier.

    using std::chrono


    For working with chrono I suggest writing using namespace std::chrono somewhere your code ( preferably at the top ). This means you don’t have to write std::chron:: in front of everything.

    Is easier to read than :

    Usually, using namespace statements are discouraged to avoid name collisions, but since we are writing std::chrono we could only get name collisions with items in the std::chrono library, which is less likely to happens.

    Includes


    To make sure everything compiles as it should, please add the headers and using to the top of your file :

    About this part


    I also want to point out that this guide is rather comprehensive. This is because it’s a good idea to have deep understanding how the various components of the chrono library works. Just writing this guide helped me to understand a lot of it. My hope is that it will help you too.

    If you want more information, you can look at the en.cppreference documentation for chrono. This resource covers most, if not all of the features in C++11 with detailed information and good examples. It’s very useful for learning and as a reference.

    Overview


    Here is a quick overview of the chrono library.

    I will now go over each of these components, starting with the basic one, ratio

    ratio


    The ratio is actually not a direct part of chrono but it’s very useful for working with chrono and just useful in general. A ratio is just that, a ratio or a fraction if you will. For example the ratio between a minute and a second is 60 / 1 since you need 60 seconds to make a minute. ration is defined in it’s own header file, simply called ratio

    Definition


    The class is templated. The definition looks like the following :

    Even though this is a templated class, which can be complicated and hard to understand, the template arguments are quite straight forwards.

    Template arguments :

    • Num  – the numerator, or simply the top part of a fraction
    • Denom  -is the denomerator or bottom part of fraction

    These two numbers forms a fractions :

    Num / Denom

    Usually these numbers are dividable by 10, so you end up with numbers like 1000 or 0.001

    Both variables are of the type std::intmax_t, which means they are the biggest possible type of signed int available, usually at least 64 bits. For example int64_t.

    Predefined ratios


    In the chrono library ticks are stored in fractions of second. A few examples :

    • A second : ratio < 1 /1 >
      • A second is 1 / 1 of a second.
      • Can also be written as std::ratio< 1 > since the denomerator defaults to 1
    • A millisecond : ratio < 1 /1000 >
      • A millisecond is 1 / 1000 of a second
    • A minute : ratio< 60 /1 >
      • A minute is 60 / 1 seconds.
      • Can also be written as ratio< 60 > since the denomerator defaults to 1

    Resource on ratios


    As a part of the ratio header, there’s a lot of predefined ratios ( milli, nano, kilo, mega, … ). Because ratio is not directly a part of the chrono library ( it has other uses than just chrono ), there is no predefined values for minutes, hours, etc. There’s just the ones based on the standard units that’s used for distance or weight. You can refer to either of these using the std:: prefix. Since the ratios are not part of the chrono library, it’s just std:: and not std::chrono::.

    For a full list of the predefined values, take a look at the documentation.

    duration


    duration( or std::chrono::duration ) is one of the basic classes of the chrono library. As the name suggests, it stores a time duration. Or a distance between to points in time if you like.

    Member variables


    It’s quite simple in its structure, it only has two member variables :

    • rep
      • an arithmetic type ( basically any unit that can hold a number ) that stores the number of ticks ( number of seconds, minutes, years, etc.. ).
    • period
      • a ration containing the type of unit rep stores. In effects this means “how many seconds/minutes/years,… is one tick.”

    Constructing a duration


    The creation of a duration is a bit complex as it involves two template arguments that sets representation type and a ratio plus the constructor.

    teamplate arguments


    The actual templated part looks like this :

    Template parameters :

    • rep – the type to hold the ticks
      • Typically int or double
    • ratio – the type units used by duration
      • Covered above

    The ratio defaults to 1 / 1, meaning seconds. The number of ticks the duration should use are sent to the constructor in the ordinary way using the parenthesis after the variable name.

    To create a duration for containing seconds, you can do :

    This creates a duration for holding seconds.

    Other ratios


    To create different durations we can use the ratio like above.  For example 10 millisecond becomes :

    We can simplify this by using the predefined ratios already in C++11 :

    Okay, but what about 10 minutes? This is quite similar to the above :

    We do std::ratio< 60, 1 > because a minute is 60 / 1 seconds which or simply 60 seconds. But we can’t simply this like above because there is not predefined ratio for minutes. The predefined ratios are all “clean” ratios like 1 / 100, 1000 / 1, 1 / 10, 10 / 1, etc…

    Predefined durations


    But there is another, even simpler way! Just like in ratio there are predefined values in duration And they’re very simple to use.

    So say you wanted a duration of 10 milliseconds :

    Or 10 minues :

    Constructor


    The duration has three major constructors

    • Default, empty constructor
      • Looks something like this : duration( )
      • Initializes the duration
    • Constructor with rep variable
      • Looks something like this : duration( rep ) where red can be int, doube or similar
      • Sets the internal tick variable to the variable passed in constructor
      • This is the one we’ve used up until now
    • Construct for other duration
      • Looks something like this : duration( duration )
      • Sets the internal tick variable based on the passed duration
      • The = operator works in the same way
    From rep type

    Takes a value ( rep ) as argument and sets the ticks of the duration to it.

    From other duration type

    Takes a duration as argument and sets the ticks of the duration to it. Will convert between the two types of duration based on the ration. This means that if you pass a minutes duration to a seconds duration, you will get the number of minutes * 60 ( because there are 60 seconds in a minute.

    Example

    This creates a 10 second duration

    Duration functions


    Duration has a few functions, but I’ll just cover two of them now

    • count
      • Returns the number of ticks
    • duration_cast 
      • Converts a duration of duration into another.

    count


    This function simply returns the number of ticks. So for our 10 millisecond example, this will be 10.

    Code example :

    Output :

    duration_cast


    When we’re working with two different types of durations things can get a bit weird. A simple example : what’s 3 minutes minus 36 seconds. The answer is quite simple for a human to figure out. But the results in your program needs to be a duration but which unit? Since 3:24 can’t be expressed exactly in minutes, we need to change either the 3 minutes to seconds, or the 36 seconds to minutes. Here’s where duration_cast<> comes in.

    This simply casts our 3 minutes into 180 seconds. After doing that, we can simply do :

    And we’ll get the result in seconds ( 144. ) If you had converted this to minutes, it would take the whole minutes and strip the seconds. Meaning you would end up with 2

    Floating points


    Up until now, we’ve only used integer values for representing ticks. This means we can only represent whole tick. So a duration of seconds using an int to represent ticks means it can only represent whole seconds. Consider the following code :

    This will fail ( won’t compile ) because you loose precision. You could use a duration_cast to fix this, but you’ll loose the precision and end up with 0duration_cast is way of telling the compiler “yeah, I know this will loose precision, just do it!”

    So instead we can create a duration of seconds represented as a double :

    Output :

    Count : 0.016

    This is not the same as the predefined duration seconds because all the predefined durations uses int.

    Unlike the previous example, this won’t fail because you don’t loose precision. In fact, you could change the ratio to store years :

    This will convert the 16 ms to years. If you did yearsAsDouble.count()
    you would get roughly 5.07356672 × 10^-9 ( 0.00000000507356672 ) years.

    Clocks


    Clocks are just objects that is used for finding the current time. They are static, which means that there will only be one of each clock type. There is also just one member function ( also static member function, now() . The function now() returns the current time as time_point. I will cover time_points later.

    Clock also have a tick rate which state how accurate they are. For instance : a clock has a tick rate of seconds, it can’t be used to measure milliseconds. The tick rates are represented as ratios.

    Clock types


    There are three available clocks in the chrono library.

    • system_clock
      • Full name : std::chrono::system_clock
      • The wall clock, use this if you just want to know the current time and date
      • This clock may be adjusted by either daylight saving time ( DST ) or leap seconds.
      • Can be mapped to C-style points and can therefore be easily printed.
    •  steady_clock
      • Full name : std::chrono::steady_clock
      • This clock is monotonic, this means will never be adjusted, so it’ll never be affected by things like DST and leap seconds
      • Best suited for measuring intervals
    •  high_resolution_clock
      • Full name : std::chrono::high_resolution_clock
      • Shortest tick available ( will be updated most often )
      • Might be alias of std::chrono::system_clock or std::chrono::steady_clock, or a third, independent clock.
        • This means it’s not guaranteed to be monotonic like steady_clock
      • Use this for benchmarking

    That’s really all you need to know about clocks, but in the next part we’ll be exploring them more.

    time_point


    time_point<( or std::chrono::time_point) is the central class of the chrono library. I’ll spare the implementation details for now and just say that it contains various information about the current point it in time.

    Construction


    The constructor for a time point looks something like this :

    As you can see, its a templated class that takes both a clock, and a duration. The duration is the duration the time_point uses. This defaults to the duration of the clock ( as you can see from the typename Clock::duration part. )

    Simplified constructor


    Luckily though don’t have to specify either of the arguments. So a really simple way to construct a time_point is :

    You can use stady_clock or system_clock instead of high_resolution_clock.

    This is equal to writing :

    A bit more complex, but it means the exact same time : a time_point that uses a high_resolution_clock and has the same duration as the high_resolution_clock. I see no reason to use this method as opposed to the simpler one, but I want to explain the template arguments as well as I can.

    Using custom ratio


    But what if we wanted to specify our own duration? Well then we have to set the second template argument as well. Say we wanted to specify milliseconds as our duration time unit. Remember that duration has predefined constants for this.

    This means we can simply do :

    Full constructor


    Now let’s do something even worse. Say we wanted a time_point that uses half minutes ( 30 seconds ) as the time units. I have no idea why anyone would want this, but it’s just a ( somewhat contrived ) example. As with some other examples, I do not encourage writing code like this. It’s horribly hard to read and very hard to understand unless you know the different part of the chrono libraries. Okay, here we go :

    Yup, that’s a template argument, inside a template argument, inside a template argument! Don’t write code like this! If you need a specific time ratio, at least put the ratio and duration in separate objects ( I’ve shown you how to use the constructors above. ) Also make sure they’re well named like ratio30sec and duration30sec. That should give the reader at least a small hope at knowing what’s going on.

    I added this example because if you understand this constructor and how it works, you understand the major parts of std::chrono

    Initialization


    As stated above, the static member function of clocks, now() returns a time_point of the current point in time.

    That means we can just use auto to create a time_point too!

    Simple as that, we’ve created a time point. The type of this object will be exactly the same as

    Only it’s even simpler, and we’ve initialized it to the current point in time at the same time!

    Difference between two time_points


    And finally we can do some actual timing! Time points supports arithmetic operations. This means you can say time_point_x - time_point_y. This will result in a duration But what is the kind of duration. Seconds? Milliseconds? Years? Actually there is no one answer, it’s implementation defined. But the result is almost certain to be less than one second.

    Since we can’t know what the resulting value is, we have two options. Say we have the following code :

    And wanted to know the result of t1 - t2 Our two options are :

    1. Use auto
        • Nice and simple
        • But we can’t control the type of result.
    2. Use duration_cast
        • Takes the result of t2 - t1 and casts it into a duration of milliseconds and uses it to set result
        • This is a bit harder, but now we have full control over the type of duration.
        • If you want higher precision, you can use microseconds or nanoseconds
        • If you want higher precision, you can use microseconds or nanoseconds

    Delta timer


    So now let’s use all this knowledge and make a delta timer. A delta timer is used in games to tell the difference between two frames. The code is relatively simple and will show one ( of many ) ways to use the chrono library.

    Notes


    1. Get the current time
      • We need this to calculate the difference in the next step
    2. Take the dif and store it in a duration
      • Stored in seconds ( since it’s the default )
      • Represented as double
    3. Reset time_prev
      • We need this point because we always need to know the time_point of the previous frame
    4. Return the results
      • Finally we return the time since last frame as fractions of a second
      • Can be a very small value like 0.000000001 ( 1ns )

    A note about time units


    This section just describes my reasoning for using seconds stored as double. It’s very focused around game programming and not crucial to understanding chrono.

    I choose to use seconds as double here because double allows higher accuracy than int. And even though the game will almost certainly use less than 1 second on one frame, using seconds over milliseconds as time units means that the number will always be on the form 0.x. It also ensure that the delta won’t be exactly 0.

    If the delta is 0 on one frame, no movement would happen ( I will get into this in the next SDL2 part ). If it only happens in one frame, the effect might not be that bad. But if it happens 100 frames in a row, that would be 100 frames without movements. And that would be bad!

    So, in my opinion, it’s better to always have a delta of 0.x as it ensure that there will always be at least a tiny fraction of movement. The fact that the delta is a small number can be countered by multiplying with a great number in the function that calculates movement ( we’ll see this in the next SDL2 part too! )

    Conclusion


    The chrono library is very useful and makes it easy to deal with timing. It enables high precision timing, and makes it easy to find difference between two points in time. There are also other libraries that uses chrono like the threading library. I might write about the threading library later. There is also a post about timing in games coming up soon ( as mentioned in the above post. )


    Feel free to comment if you have anything to say or ask questions if anything is unclear. I always appreciate getting comments.

    You can also email me : olevegard@headerphile.com
    Share

    [ C++11 – Part 1 ] Enum class

    Introduction to the series


    I thought I’d start of by talking about my favorite thing that’s new about C++11 standard. C++11 has a lot of useful new features : auto, initializer lists, lambda, shared_ptr, unique_ptr, move semantics, etc. Some of these are quite comprehensive and complicated, and I’m still working on understanding all of them. But this one is actually quite simple.

    About enum classes


    Enum classes are basically enumerations that can’t implicitly be converted to integer types. So basically you can’t write :

    Why is this such a good thing?


    First of all it helps code clarity. A simple question : Say you have an enum of card suits, which would you prefer?

    Using and enforcing enum classes means you’ll instantly know what the value is, so you’ll never have to find the actual definition of the enum and look up what the different int values does.

    So it helps code clairty. Is that all?


    No! There are more serious issues. Say you have the following code

    This might look okay, they both set the card to Suit::Clover. But here comes the big issue. Someone changes the order of the elements in Suit.

    What’s the issue?


    It might seem a very subtle change. But you let’s say you implemented reset method a long time ago. It’s been working fine ever since, and you’ve completely forgotten that it uses and integer value to set suit. It’ll now do something different from the constructor! So you end up with cards being different when you reset them from when you create them. And issues like this can be very confusing and hard to debug.

    This is just a minimal example to showcase the issue. But this can happen just as easily in huge projects where the enum is used hundreds of places. Debugging such issues will waste a huge amount of time and cause a whole lot of pain and agony. All because of using an integer to assign an enum! Using enum class prevents these issues.

    Conclusion


    Use enum classes! It might be a bit annoying having to write the full enumeration name sometimes. But it’s a lot better than spending hours upon hours debugging when someone changes the order of the enumeration items or adds a new value in front of others!


    Feel free to comment if you have anything to say or ask questions if anything is unclear. I always appreciate getting comments.

    You can also email me : olevegard@headerphile.com
    Share