为MyVector创建push_back()函数

Creating a push_back() function for MyVector

本文关键字:函数 back MyVector 创建 push      更新时间:2023-10-16

我正在尝试使用类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

编辑

grow函数()

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;
}

正如其他地方所指出的,您有几个一对一的错误,并且此代码在异常安全方面也失败了。


注释原始代码:

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

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

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

即使大小<max。那么,max是什么意思呢?另外,如果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;
  }
}

两个错误:

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];
    }

多个错误,例如在输入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;
}

++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];
}

总而言之,当我检查出这个答案时,这是最终对我有效的代码。变量名称略有不同。我相信我的ptr是原始海报的v.

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;
}