简体   繁体   中英

New C++ Template class Constructor that takes a type of itself as an argument

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

 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 (ie 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

"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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM