C ++ Глубокая копия динамического массива через оператор присваивания - PullRequest
2 голосов
/ 05 октября 2019

Я пытаюсь скопировать динамически размещенный массив в экземпляр. Мой код, кажется, копирует значения, но ему также нужно изменить размер массива, чтобы он соответствовал массиву размера "& other".

Небольшая информация о коде: под рукой два класса, один "Фильм ", который принимает название, время фильма и режиссера (все указатели) в качестве частных участников. Есть еще одна, называемая «MovieCollection», которая представляет собой массив, в котором хранится каждый экземпляр «Movie» в данном индексе.

//These are private member variables:`

int ArrySize = 50; //There is another section of code that points to this and resizes if needed, I believe it needed a size at runtime though.

//Array to store instance of "movie"
Movie *movieArry = new Movie[ArrySize];

//This is assignment operator
const MovieCollection& operator=(const MovieCollection& other)
{ 
  delete []movieArray;
  int otherSizeArry = other.ArrySize;
  Movie* temp;
  temp = new Movie[otherSizeArry];

  for (int i = 0; i < otherSizeArry; i++)
  temp[i] = other.movieArry[i];

  return *this;
  delete []temp;
}

Я использовал другую функцию, которую я написал, для изменения размера массива во время создания экземпляра. Например, экземпляр, который я хочу скопировать, имеет 10 индексов, но новый экземпляр, в который я пытаюсь скопировать значения, все еще имеет ограничение 50. Из того, что я понимаю, я должен удалить его, потому что размеры массивов не могут быть изменены, затем скопируйтеновый размер закончен (вместе со значениями).

Любая помощь будет принята с благодарностью и заранее благодарим вас. Кроме того, извините, если требуется больше кода. Я не хотел давать больше, чем нужно.

1 Ответ

1 голос
/ 05 октября 2019

Ваш оператор присваивания выполнен неправильно. Он освобождает массив movieArray перед выделением нового массива temp. Если распределение завершится неудачно, класс останется в плохом состоянии. И вы не присваиваете массив temp для movieArray перед вызовом return *this; (delete []temp никогда не достигается, компилятор должен был предупредить вас об этом).

Оператор должен выглядеть больше какэто вместо этого:

MovieCollection& operator=(const MovieCollection& other)
{ 
    if (&other != this)
    {
        int otherSizeArry = other.ArrySize;
        Movie* temp = new Movie[otherSizeArry];

        for (int i = 0; i < otherSizeArry; ++i) {
            temp[i] = other.movieArry[i];
        }
        // alternatively:
        // std::copy(other.movieArry, other.movieArry + otherSizeArry, temp);

        std::swap(movieArray, temp);
        ArrySize = otherSizeArry;

        delete[] temp;
    }

    return *this;
}

Если в вашем классе есть конструктор копирования (и он должен - если нет, вам нужно добавить его), реализация оператора присваивания может быть значительно упрощена:

/*
MovieCollection(const MovieCollection& other)
{
    ArrySize = other.ArrySize;
    movieArray = new Movie[ArrySize];

    for (int i = 0; i < ArrySize; ++i) {
        movieArray[i] = other.movieArry[i];
    }
    // alternatively:
    // std::copy(other.movieArry, other.movieArry + ArrySize, movieArray);
}
*/

MovieCollection& operator=(const MovieCollection& other)
{ 
    if (&other != this)
    {
        MovieCollection temp(other);
        std::swap(movieArray, temp.movieArray);
        std::swap(ArrySize, temp.ArrySize);
    }

    return *this;
}
...