为MyVector创建push_back()函数

时间:2013-12-07 17:18:36

标签: c++

我正在尝试使用我的类MyVector重新创建一个向量。 我坚持创建function push_back()

这是MyVector

template<class T>
class MyVector{
    private:
        T *v;
        int size;
        int max;

    public:
        MyVector();
        MyVector(int n);
        MyVector(int n, int k);
        MyVector(const MyVector &l);
        void grow();
        MyVector<T>& operator=(const MyVector &lhs);
        T &operator[](unsigned int i);
        void push_back(T t);
        int capacity();
        int length();
        void reserve (int n);
        void resize(int);
};

我的push_back()功能

template<class T>
void MyVector<T>::push_back(T t) {
    T *temp = v;
    v = new T[++size];
    temp[size] = t;

    for (int i = 0; i < size + 1; ++i){
        v[i] = temp[i];
    }

    delete [] temp;
}

我的司机程序

int main() {
    MyVector<int> a(5, 1);
    a.push_back(9);

    for (int i = 0; i < a.length(); i++) {
        cout << a[i] << " ";
    } cout << endl;

    return 0;
}

和我的输出

1 1 1 1 1 0

修改

成长函数()

template<class T>
void MyVector<T>::grow() { 
    MyVector *temp = v;

    v = new T[max * 2];

    for (int i = 0; i < capacity; ++i){
        v[i] = temp[i];
    }
    delete [] temp;
    max = max * 2;
}

5 个答案:

答案 0 :(得分:2)

正如其他地方所指出的那样,你有一些一对一的错误,而且这个代码在异常安全时也失败了。


带注释的原始代码:

template<class T>
void MyVector<T>::push_back(T t) {

按值取值,而不是const引用和/或通用或rval引用,强制复制此处

    T *temp = v;
    v = new T[++size];

您在每个push_back上重新分配您的数组,即使大小&lt;最大。那么,最大的是什么? 另外,如果new在这里抛出bad_alloc会发生什么?

    temp[size] = t;

您将新值复制到数组中,该数组对于它来说太小了。您将较大的数组放在v中。 如果T的复制构造函数抛出异常,会发生什么?您的旧数组将被泄露,但您已更新sizev以反映未初始化的最后一个元素。

    for (int i = 0; i < size + 1; ++i){
        v[i] = temp[i];
    }

请记住,temp是旧数组,因此它有size-1个元素。你正在复制结束。

    delete [] temp;
}

建议

  • 您已经拥有reserve方法。为什么不调用它来保证足够的空间,然后只增加大小并构造新元素?
  • 在可能抛出的所有内容成功之前,不要修改您的结构

例如

template <typename T>
void MyVector<T>::push_back(T const &t) {
  reserve(size+1); // if this doesn't throw, we now have enough room
  v[size] = t;     // if this doesn't throw, the hard work is done
  ++size;
}

现在你只需要正确地写reserve ...这个样本不能处理收缩,但至少是异常安全的

template <typename T>
void MyVector<T>::reserve(size_t newsize) {
  if (newsize > max) {
    size_t newmax = std::max(newsize, max*2);
    std::unique_ptr<T[]> newv(new T [newmax]);
    std::copy(v, v+size, newv.get());
    std::unique_ptr<T[]> oldv(v);
    v = newv.release();
    max = newmax;
  }
}

答案 1 :(得分:1)

++size增加大小,因此temp[size - 1]成为数组中的最后一个元素。该数组的大小仅为size,因此您的for-loop也是错误的。 你的行:

temp[size] = t; //change to size - 1
for(int i = 0; i < size + 1; ++i) //change to i < size

所以:

temp[size - 1] = t;
     ^^^^^^^^
for (int i = 0; i < size - 1; ++i){
                         ^^^
    v[i] = temp[i];
}

答案 2 :(得分:1)

两个错误:

v = new T[++size];
    v[size-1] = t;// should be v and not temp

    for (int i = 0; i < size - 1; ++i){// should run till size-2 since size-1 is already copied.
        v[i] = temp[i];
    }

答案 3 :(得分:1)

多个错误,例如在输入push_back之前大小为10:

template<class T>
void MyVector<T>::push_back(T t) {
    T *temp = v; // size = 10, temp is an array from 0 to 9
    v = new T[++size]; // size = 11, v is an array from 0 to 10
    temp[size] = t; // accessing temp[11] when there is 0-9 only, first error !

    for (int i = 0; i < size + 1; ++i){ // looping from 0 to 11 when temp is 0-9 and v 0-10, second error !
        v[i] = temp[i];
    }

    delete [] temp;
}

答案 4 :(得分:0)

总结一下,当我查看这个答案时,这里的最终代码最终为我工作了。变量名称略有不同。我相信我的ptr是原创海报的诉讼。

template<typename T>
void MyVector<T>::push_back(const T & value){
    T *temp = ptr;
    ptr = new T[++s];
    ptr[s-1] = value;
    for (int i = 0; i < s - 1; ++i){
        ptr[i] = temp[i];
    }
    delete [] temp;
}