I’m working on a template Class in C++ similar to the ArrayList in java (yes I know vector does the same thing, this is not a utilitarian coding project).
I figured it would be useful to have a Constructor for my ArrayList class that takes another ArrayList as an argument to seed the ArrayList. But when I try and write the constructor I get this error
invalid constructor; you probably meant 'ArrayList<T> (const ArrayList<T>&)'
Does this mean that the ArrayList has to be a constant? And why do I need the addressof operator?
I’m still learning the ropes of C++ so I’m a bit confused.
The prototypes are here:
ArrayList(ArrayList<T> list);
ArrayList(ArrayList<T> list, int size);
The code is here:
/**
* Creates an ArrayList of type T that is twice the
* size of the passed in ArrayList, and adds all elements
* from the passed ArrayList<T> list, to this ArrayList.
*
* Runs in O(n) time, where n = the size of list.
*
* @param list the ArrayList to use as a seed for this ArrayList.
*/
template<class T>
ArrayList<T>::ArrayList(ArrayList<T> list) {
array = new T[list.getSize() * 2];
capacity = list->getSize() * 2;
size = list->getSize();
for (int i = 0; i < list->getSize(); i++) {
array[i] = list->get(i);
}
}
Edit
The below code gets no errors, while the above does…..
/**
* Creates an ArrayList of type T that has a capacity equal to the passed
* in theCapacity parameter. This ArrayList starts with the passed ArrayList.
*
* Note: If the passed in capacity is smaller than the size of the passed in
* ArrayList, then the capacity is set to twice the size of the
* passed ArrayList.
*
* @param list the ArrayList to use as a seed for this ArrayList.
* @param theCapacity the capacity for this ArrayList.
*/
template<class T>
ArrayList<T>::ArrayList(ArrayList<T> list, int theCapacity) {
if (theCapacity >= list->getSize()) {
array = new T[theCapacity];
capacity = theCapacity;
}
else {
array = new T[list->getSize() * 2];
capacity = list->getSize() * 2;
}
size = list->size;
for (int i = 0; i < size; i++) {
array[i] = list->get(i);
}
}
Use
as your constructor signature to pass the arraylist as a
constreference. This is the proper signature for a copy constructor. Both the implementation and calling code needn’t change, unless you are modifyinglistwithin your ctor.When you do
ArrayList<T>::ArrayList(ArrayList<T> list)you are creating a temporary copy of the entire ArrayList instance. (You mustn’t do this for ctors since it will invoke infinite recursion, as the new copy oflistwill use the same function definition and so on).ArrayList<T>::ArrayList(ArrayList<T>& list)passes the list as a reference, meaning it is no longer what is often called “pass by value” and work on the exact version of the list from the calling code.By accepting a const reference in a function, you are saying that the function will not modify the contents of the reference (i.e. not do any modifying operations on it : it will be constrained to only
constaccesses). You should read aboutconst, references and copy constructors before going further.Update:
For pass by value or reference, you can access members via the
obj.membersyntax. If you were passing a pointer likeArrayList<T>::ArrayList(ArrayList<T>* list), you would have to uselist->membersyntax or(*list).membersyntax, not to mention checking if list is0/nullptrfirst (you can’t dereference null pointers).You are mixing syntax for pointers and syntax for value/references. convert all of your
list->xintolist.xsince you aren’t passing thelistargument using pointers.See this for different passing behaviours: http://ideone.com/3c5mJ