I am a new C++ developer who, coming from Java, am having issues in understanding some of C++'s key memory management features. Below is my attempt at an ArrayList implementation and I would really love criticism and ways to improve.
Problems I noticed: Can not create an ArrayList object
Questions:
In expandArray(), is delete[] required since the data is set in the next line?
In my functions such as add(T &d) I figured the parameter should be a reference. Is this necessary? Would the program still work with the variable as a reference?
There is no null value in C++ (besides with pointers), so in my function get(int index) I just use return; for a value it could not find.
ArrayList.h:
#pragma once
template <class T> class ArrayList {
public:
// Constructor to initialize the list.
ArrayList();
// Destructor to clean up the list.
~ArrayList();
// Finds a specifies element of the array list based on the index. Returns null if nothing.
T get(int index);
//Finds the index of the given element.
int indexOf(T &d);
// Inserts an element at the end of the list.
void add(T &d);
// Inserts an element at a specified position in the array list.
void add(T &d, int position );
// Deletes the element at the given index.
//TRUE if successful
bool remove(int index);
//TRUE if this array contains the given data
bool contains(T &d);
// Empties/clears out the array list structure.
void clear( );
// Tests to see if the array list structure is empty.
bool isEmpty( );
// Returns the size of the array.
inline int listSize() { return size; }
private:
int arraySize;// Size of the array.
int size; // Number of elements in the array.
T *data = nullptr;// Pointer to the array.
// Checks if the array is full of elements.
bool needsExpansion();
//makes space in the array by doubling the arraySize
void expandArray();
//returns TRUE if the given index is in range (0 -> size)
bool isValidIndex(int index);
};
ArrayList.cpp:
#include "ArrayList.h"
using namespace std;
//constructor
//set array size, size and data
template<class T>
ArrayList<T>::ArrayList() {
arraySize = 2;
size = 0;
data = new T[arraySize];
}
//deconstructor
//cleanup objects
template <class T> ArrayList<T> :: ~ArrayList() {
// delete arraySize;
// delete size;
delete []data;
};
//takes in and index and returns the object associated with it
//return NULL or nothing if index is outta range
template <class T> T ArrayList<T> :: get(int index) {
if (!isValidIndex(index)) return 0;
return data[index];
}
//returns the index of the given obj
//or -1 if not found
template <class T> int ArrayList<T> :: indexOf(T &d) {
for (int i = 0; i < size; i++) {
if (data[i] == *d) return i;
}
return -1;
}
//adds the given data to the end of the list
//expands the list if neccisary
template <class T> void ArrayList<T> :: add(T &d) {
if (needsExpansion()) expandArray();
data[size++] = d;
}
//adds the given data to the given index
//expands the list if necessary
template <class T> void ArrayList<T> :: add(T &d, int index) {
if (needsExpansion()) expandArray();
//accept index at size
if (!(index >= 0 && index <= size)) return;
//move all obj's at >= index up 1
for (int i = size() - 1; i >= 0; i--) {
if (i >= index) {
data[i + 1] = data[i];
}
}
data[index] = d;
size++;
}
//removes the element at the given index
template <class T> bool ArrayList<T> :: remove(int index) {
if (!isValidIndex(index)) return false;
//shift elements down
for (int i = index + 1; i < size(); i++) {
data[i - 1] = data[i];
}
//remove last element
data[size--] = nullptr;
return true;
}
//TRUE if the element exists in the array
//FALSE otherwise.
template <class T> bool ArrayList<T> ::contains(T &d) {
return indexOf(d) >= 0;
}
//clears out the data that this arraylist holds
template <class T> void ArrayList<T> :: clear() {
size = 0;
arraySize = 2;
delete []data;
*data = new T[arraySize];
}
//TRUE if this array list has no elements.
template <class T> bool ArrayList<T> :: isEmpty() {
return size == 0;
}
//TRUE if this array needs to be expanded.
//needs expansion if it is full.
template<class T> bool ArrayList<T> :: needsExpansion() {
return size >= arraySize;
}
//expands the array by twice the given size
template<class T> void ArrayList<T> :: expandArray() {
arraySize *= 2;
T *newData = new T[arraySize];
for (int i = 0; i < size; i++) {
newData[i] = data[i];
}
delete []data;
data = newData;
}
//check if the index is valid
template<class T>
bool ArrayList<T>::isValidIndex(int index) {
return index >= 0 && index < size;
}
It compiles after adding #pragma once.