I am trying to implement a dynamic array:
template <typename Item>
class Array {
private:
Item *_array;
int _size;
public:
Array();
Array(int size);
Item& operator[](int index);
};
template <typename Item>
Array<Item>::Array() {
Array(5);
}
template <typename Item>
Array<Item>::Array(int size) {
_size = size;
_array = new Item [size];
for (int i = 0; i < size; i++)
cout << i << " " << _array[i] << " " << &_array[i] << endl;
}
template <class Item>
Item& Array<Item>::operator[](int index) {
if (index < 0 || index > _size-1)
cout << "this: " << this << ". Index out of range" << endl;
return _array[index];
}
When used like this, it works as expected, i.e. prints 5:
Array< int > testArray(5);
testArray[0] = 5;
cout << testArray[0] << endl;
However, I would like to use the class for a two-dimensional dynamic array. I thought that the following would just magically work and print 5…
Array< Array<int> > testArray(5);
testArray[0][0] = 5;
cout << testArray[0][0] << endl;
…but it does not work. It crashes when I try to set the value at [0][0]. The debugger shows me that this has _size set to 0 and _array to NULL. this at that point points to the first element of the _array of the last created Array instance.
One of the things I don’t get is when the “inner” array calls its constructor. Stepping through the code, I see that Array(int size) is called once and Array() five times. I would like to create the inner array with a specific size, but using Array< Array<int>(10) > testArray(5) does not compile.
Could you provide me with some insight on this? It seems I could not quite wrap my head around templates yet…
You cannot chain constructor calls in C++. Your first constructor implementation does nothing, so the 5 instances contained in the parent
Arrayend up being uninitialized, resulting in undefined behavior.To fix, you can either add a default value to the
sizeparameter of the other constructor, or factor out the initialization logic in a separate (private) function, and call it from both constructors.EDIT: The reason why the first constructor does nothing is that the line
does not call the constructor of the current instance, but instead allocates a new (unnamed) temporary
Arrayinstance, which is immediately destructed at the end of the line.