как иметь конструктор копирования для вектора? - PullRequest
1 голос
/ 29 апреля 2020

Я смоделировал вектор, но конструктор не работает; когда я вызываю 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();

}

Ответы [ 2 ]

1 голос
/ 29 апреля 2020

Проблема в строке test1 = test;// problem, которая вызывает не конструктор копирования, а оператор присваивания. Вы не объявляли этот оператор, поэтому компилятор будет использовать реализацию по умолчанию, которая просто копирует все члены. Таким образом, после присвоения test1.vec и test.vec указывают на одну и ту же ячейку памяти.

Когда вы измените строку (и ту, что над ней) на vector <int > test1{test};, она вызовет ваш конструктор копирования.

Вы также забыли #include <cstring> для memcpy, который не следует использовать для типов без POD.

Вы должны умножить размер в memcpy на sizeof(T), потому что memcpy работает с байтами, а не с типами. Вы также должны использовать v.vec вместо v.

Вот фиксированная версия: https://ideone.com/JMn7ww

0 голосов
/ 29 апреля 2020

Я думаю, что проблема в вашем операторе копирования. Вы используете memcpy(), которая является c функцией. Что само по себе не должно быть проблемой (кроме того, что это не так приятно во многих отношениях) Но поскольку memcpy () является функцией c, она не знает о типах и принимает аргументы своего размера в виде количества байтов.

элемент, который вы вставили, равен int, что, вероятно, составляет 4 байта. Поэтому, когда вызывается ваш экземпляр contstructor, а оригинал содержит 3 элемента, в вашем массиве будет 12 байт, но mallo c скопирует только 3 из них.

Комментарии других людей о неправильных комментариях Копирование шаблонов правильное, поэтому, если вы создадите вектор строк, вы не сможете просто запоминать их и предполагать, что результатом будут новые строки. Для этого ответа я предполагал, что вы используете только базовые c типы в качестве аргументов шаблона, такие как int или double.

...