【问题标题】:how to have a copy constructor for vector?如何有一个向量的复制构造函数?
【发布时间】:2020-08-13 05:14:46
【问题描述】:

我模拟了一个向量,但构造函数不起作用;当我调用 pop() 函数时,它会将垃圾值分配给向量类中的旧对象。

    vector(vector &v) {
        vec = new T[v.size()];
        memcpy(vec, v,v.size());
        size_arr = v.size();
    }

这是完整的代码:

#include <iostream>
using namespace std;

template <typename T>
class vector {
    int size_arr;
    T * vec = new T;
public:
    vector(/*int _size*/) {
        vec = new T[0];
        size_arr = 0;
    };
    ~vector() {
        size_arr = 0;
        delete[] vec;
    };
    vector(vector &v) {
        vec = new T[v.size()];
        memcpy(vec, v,v.size());
        size_arr = v.size();
    }
void push_back(T data) {
    T *temp = new T[size_arr + 1];
    for (int i = 0; i < size_arr; i++)
        temp[i] = vec[i];
    temp[size_arr] = data;
    size_arr++;
    delete[] vec;
    vec = temp;
};
void push_front(T data){
    int j;
    T *temp = new T[size_arr + 1];
    for ( j = size_arr; j >= 0;j--) {
        temp[j + 1] = vec[j];
    }
    temp[0] = data;
    delete[] vec;
    vec = temp;
    size_arr++;
};
void insert(int index, T data) {
    int j;
    T *temp = new T[size_arr + 1];
    for (int i = 0; i < size_arr ;i++)
        temp[i] = vec[i];
    for (int i = 0; i < size_arr;i++) {
        if (i == index) {
            for ( j = size_arr; j >=i;j--) {
                temp[j+1] = vec[j];
            }
            temp[j + 1] = data;
            delete[] vec;
            vec = temp;
            size_arr++;
        }
    }
};
void pop() {
    T *temp = new T[size_arr - 1];
    for (int i = 0; i < size_arr-1;i++)
        temp[i] = vec[i];
    size_arr--;
    delete[] vec;
    vec = temp;
};
void Delete(int index) 
{
    T *temp = new T[size_arr - 1];
    for (int i = 0; i < index;i++) 
        temp[i] = vec[i];
    for (int i = 0; i < size_arr;i++) {
        if (i == index) {
            for (int j = i; j < size_arr-1;j++) {
                temp[j] = vec[j + 1];
            }
            size_arr--;
            delete[] vec;
            vec = temp;
        }
    }
};
int search(T data) {
    for (int i = 0; i < size_arr;i++) {
        if (vec[i] == data) {
            return i;
        }
    }
    return -1;
};
int size() { return size_arr; };
};

int main() {
    vector <int>test;
    test.push_front(2);
    test.push_front(3);
    test.push_back(0);
    test.push_back(-1);
    test.insert(2, 2);
    test.pop();

    vector <int > test1;
    test1 = test;//  problem
    test1.pop();

}

【问题讨论】:

  • 您声明了一个复制构造函数,但test1 = test;// problem 将使用赋值运算符。
  • 不要使用memcpy,当你实例化一个不平凡的向量时,它会给你未定义的行为,比如std::string。 (另外,memcpy(vec, v,v.size()); 不应该编译,所以我不相信这是你的真实代码。)

标签: c++ function vector copy-constructor assign


【解决方案1】:

问题出在test1 = test;// problem这一行,它没有调用复制构造函数,而是赋值运算符。您没有声明此运算符,因此编译器将使用默认实现,它只是复制所有成员。所以,赋值后test1.vectest.vec指向同一个内存位置。

当您将这一行(以及它上面的那一行)更改为vector &lt;int &gt; test1{test}; 时,它将调用您的复制构造函数。

您还忘记了 #include &lt;cstring&gt;memcpy,您不应该将其用于非 POD 类型。

您必须将memcpy 中的大小与sizeof(T) 相乘,因为memcpy 适用于字节,而不适用于类型。您还必须使用v.vec 而不是v

这里是固定版本:https://ideone.com/JMn7ww

【讨论】:

    【解决方案2】:

    我认为问题出在您的复制操作员上。您使用 memcpy() 这是一个 c 函数。这本身应该不是问题(除了在许多意见中它不是那么好)。但是由于 memcpy() 是一个 c 函数,它不知道类型,并且将其大小参数作为字节数。

    您输入的元素是int,可能是 4 个字节。因此,当您的复制构造函数被调用,并且原始构造函数有 3 个元素时,您的数组中将有 12 个字节,但 malloc 只会复制其中的 3 个。

    其他人关于不正确复制模板类型的 cmets 是正确的,所以如果你制作一个字符串向量,你不能只是 memcpy 它们,并假设结果将是新字符串。对于这个答案,我假设您只使用基本类型作为模板参数,如 int 或 double。

    【讨论】:

      猜你喜欢
      • 2019-04-17
      • 2017-06-11
      • 1970-01-01
      • 1970-01-01
      • 2015-12-27
      • 1970-01-01
      • 1970-01-01
      • 2011-08-22
      • 2016-09-19
      相关资源
      最近更新 更多