4

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);
    }
}
Ethan
  • 1,206
  • 3
  • 21
  • 39

2 Answers2

3

Use

 ArrayList<T>::ArrayList(const ArrayList<T>& list)

as your constructor signature to pass the arraylist as a const reference. This is the proper signature for a copy constructor. Both the implementation and calling code needn't change, unless you are modifying list within 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 of list will 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 const accesses). You should read about const, references and copy constructors before going further.

Update:

For pass by value or reference, you can access members via the obj.member syntax. If you were passing a pointer like ArrayList<T>::ArrayList(ArrayList<T>* list), you would have to use list->member syntax or (*list).member syntax, not to mention checking if list is 0/nullptr first (you can't dereference null pointers).

You are mixing syntax for pointers and syntax for value/references. convert all of your list->x into list.x since you aren't passing the list argument using pointers.

See this for different passing behaviours: http://ideone.com/3c5mJ

Preet Kukreti
  • 8,417
  • 28
  • 36
  • When I switch to that though i get this error on the contents of the constructor base operand of '->' has non-pointer type 'const ArrayList' if i'm using the addressof how can it be a non pointer type?! :? – Ethan Aug 10 '12 at 02:39
  • @Ethan now that its a reference, you can use `obj.member` syntax just as you would in pass by value. This is how references work in C++. – Preet Kukreti Aug 10 '12 at 02:43
  • that means that you have some problem with implementation of your functions. You need to give us more details how you implement the class and use it. – klm123 Aug 10 '12 at 02:45
  • I have test code for all of my functions and they function fine in there so I don't think the problem lies with my functions. Also it's very odd....in one of the constructors, I already had the -> operator and I get no errors on it (but if I switch to the simple obj.memberFunction() syntax, I get an error: Invalid arguments ' Candidates are: int getSize() ' Whilst on the other constructor I get the non pointer type error with the -> operator, and with the .functionMember() syntax I get the same error as above....I'm so lost – Ethan Aug 10 '12 at 02:53
2

"const" is used because it is reference on some object, which you will not change. reference is used because this is copy constructor and default syntax suppose reference.

But the most important: You can define and use this constructor in the Exactly Same way as the one you trying to write.

klm123
  • 12,105
  • 14
  • 57
  • 95