New C ++ Template类构造函数,它将自身类型作为参数

时间:2012-08-10 02:29:40

标签: c++ templates constructor

我正在使用C ++中的模板类,类似于java中的ArrayList(是的,我知道vector也做同样的事情,这不是一个实用的编码项目)。

我认为为我的ArrayList类创建一个Constructor会很有用,它将另一个ArrayList作为参数来播种ArrayList。但是当我尝试编写构造函数时,我得到了这个错误

invalid constructor; you probably meant 'ArrayList<T> (const ArrayList<T>&)'

这是否意味着ArrayList必须是常量?为什么我需要addressof运算符?

我还在学习C ++的绳索,所以我有点困惑。

原型在这里:

    ArrayList(ArrayList<T> list);
    ArrayList(ArrayList<T> list, int size);

代码在这里:

/**
 * 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);
    }
}

修改 下面的代码没有错误,而上面的代码确实.....

/**
 * 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);
    }
}

2 个答案:

答案 0 :(得分:3)

使用

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

作为构造函数签名,将arraylist作为const引用传递。这是复制构造函数的正确签名。除非您在ctor中修改list,否则实现和调用代码都不需要更改。

执行ArrayList<T>::ArrayList(ArrayList<T> list)时,您正在创建整个ArrayList实例的临时副本。 (你不能为ctors执行此操作,因为它将调用无限递归,因为list的新副本将使用相同的函数定义,依此类推)。

ArrayList<T>::ArrayList(ArrayList<T>& list)将列表作为引用传递,这意味着它不再是通常所谓的“按值传递”并从调用代码处理列表的确切版本。

通过接受函数中的const引用,您说该函数不会修改引用的内容(即不对其执行任何修改操作:它将仅限于const次访问)。在进一步讨论之前,您应该阅读const,引用和复制构造函数。

<强>更新

对于按值或引用传递,您可以通过obj.member语法访问成员。如果您传递的指针如ArrayList<T>::ArrayList(ArrayList<T>* list),则必须使用list->member语法或(*list).member语法,更不用说检查列表是0 / nullptr首先(你不能取消引用空指针)。

您正在混合指针的语法和值/引用的语法。将所有list->x转换为list.x,因为您没有使用指针传递list参数。

了解不同的传递行为:http://ideone.com/3c5mJ

答案 1 :(得分:2)

使用“const”是因为它是某个对象的引用,您不会更改它。 使用引用,因为这是复制构造函数和默认语法假设引用。

但最重要的是:您可以以与您尝试编写的方式完全相同的方式定义和使用此构造函数。