This is about the way it is done. For your implementation I can offer several improvements.
1) Better order just a raw memory. We do not want to spend resources on the creation of objects by default? What if there is a connection to the database in the constructor, or a file is read from the disk. Resizing your vector can take a lot of time.
You can get a piece of memory for 10 objects of type T calling ::operator new(sizeof(T) * 10);
Std :: uninitialized_copy will help to fill the raw memory with existing objects
2) Order the memory with a margin. Increase the size by 2-3 times. Such a move will allow you to perform memory re-ordering and copying of elements much less frequently.
3) Use placement new instead of operator = . If you follow the first advice, then this item can be considered not as advice, but as a rule, since you cannot call the operator=() method on an uninitialized memory location. And the user of your vector is not obliged to define operator=() .
Thus, this code:
template<class T> class Vector{ T *items; //... void push(const T &value){ //... items[size] = value; ++size; } };
should be like this:
template<class T> class Vector{ T *items; //... void push(const T &value){ //... new (items + size)(value); ++size; } };
4) With regard to the pop function, do not give the memory already occupied. It may well be useful to you. In order to free up excess memory, make a special method. In std::vector it's called shrink_to_fit