4

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

我认为为我的 ArrayList 类提供一个构造函数会很有用,它接受另一个 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);
    }
}
4

2 回答 2

3

采用

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

作为您的构造函数签名,以将数组列表作为const参考传递。这是复制构造函数的正确签名。实现和调用代码都不需要更改,除非您list在 ctor 中进行修改。

当您这样做时,ArrayList<T>::ArrayList(ArrayList<T> list)您正在创建整个 ArrayList 实例的临时副本。(您不能对 ctor 执行此操作,因为它会调用无限递归,因为新副本list将使用相同的函数定义等等)。

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

通过在函数中接受 const 引用,您是说该函数不会修改引用的内容(即不对它进行任何修改操作:它将被限制为仅const访问)。在继续之前,您应该阅读 about const、references 和 copy constructors。

更新:

对于按值传递或引用传递,您可以通过obj.member语法访问成员。如果你传递一个类似的指针ArrayList<T>::ArrayList(ArrayList<T>* list),你将不得不使用list->member语法或(*list).member语法,更不用说检查 list 是否是0/ nullptrfirst (你不能取消引用空指针)。

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

看到这个不同的传递行为:http: //ideone.com/3c5mJ

于 2012-08-10T02:34:25.847 回答
2

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

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

于 2012-08-10T02:41:18.847 回答