C++98 inherited C’s only built-in container, the array. Arrays of non-class types behave in exactly the same way as they do in C. For class types, when an array is constructed the default constructor is called on each element in the array
Explicitly initialising objects in an array is one of the few times you can explicitly invoke a class’s constructor.
For track, the non-default constructor is called for first three elements, followed by default (no parameter) constructor for the last two elements; hence they are 0.0.
(Note the performance implications of this – five constructor calls will be made whether you explicitly initialise the objects or not.)
Arrays are referred to as ‘degenerate’ containers; or, put more antagonistically: they are a lie.
Arrays are basically a contiguous sequence of memory, pointers, and some syntactic sugar. This can lead to some disturbing self-delusion on the part of the programmer.
Despite the fact that the declaration of process() appears to specify an array of five Position objects, it is in fact a simple Position* that is passed. This explains why the array_sizeof macro fails (since the size of a Position is greater than the size of a pointer!). It also explains why we can increment the array name (which should be a constant) – as it is in main())
In C++11, use of ‘raw’ arrays is undesirable; and there are more effective alternatives.
std::array is fixed-size contiguous container. The class is a template with two parameters – the type held in the container; and the size.
std::array does not perform any dynamic memory allocation. Basically, it’s a thin wrapper around C-style arrays. Memory is allocated – as with built-in arrays – on the stack or in static memory. Because of this, and unlike std::vector, std::arrays cannot be resized.
If C-style notation is used there is no bounds-checking on the std::array; however, if the at() function is used an exception (std::out_of_range) will be thrown if an attempt is made to access outside the range of the array.
std::arrays also have the advantage that they support all the facilities required by the STL algorithms so they can be used wherever a vector or list (etc.) could be used; without the overhead of dynamic memory management.
Finally, because container types are classes (not syntactic sugar) they can be passed around the system like ‘proper’ objects.
Can’t wait? Download the full set of articles as a PDF, here.
To learn more about Feabhas’ Modern C++ training courses, click here.
- Practice makes perfect, part 3 – Idiomatic kata - February 27, 2020
- Practice makes perfect, part 2– foundation kata - February 13, 2020
- Practice makes perfect, part 1 – Code kata - January 30, 2020
Glennan is an embedded systems and software engineer with over 20 years experience, mostly in high-integrity systems for the defence and aerospace industry.
He specialises in C++, UML, software modelling, Systems Engineering and process development.