Мне нужно проверить, если выдается исключение из оператора =? - PullRequest
0 голосов
/ 30 июня 2018

С учетом следующего кода:

template <class T>
class A {
     T* arr;
     int size;
public:
A(int size) : arr(new T[size]) , size(size) {
}
//..

A& operator=(const A& a){
     if(this == &a){
          return *this;
     }
     this->size = a.size;
     T* ar=new T[a.size];
     for(int i=0 ; i<size ; i++){
          ar[i]=a.arr[i]; // I need to do it at "try-catch" ?
     }
     delete[] this->arr;
     this->arr=ar;
     return *this;
}
     //...
};

Когда я копирую элементы из данного массива, мне нужно делать это с предложением try-catch или нет? Это хорошая идея или нет?

1 Ответ

0 голосов
/ 02 июля 2018

Я вижу, что потенциально ваша T-копия может выдать из-за ошибки собственного выделения или по другим причинам.
С другой стороны, ваша копия A может уже сгенерировать, потому что произошел сбой выделения памяти.

В настоящее время вам потребуется обработать уничтожение, поскольку вы не бетонировали выделенный вами массив, и все созданные вами экземпляры T необходимо уничтожить, если одно из них является исключением, возможно, из-за сбоя выделения.

Один быстрый способ исправить это - сохранить массив в unique_ptr. Тогда он будет уничтожен при выходе из контекста.

Другим способом может быть пересмотр вашего контракта на А после того, как присвоение исключено: оно должно быть действительным, то есть сохраняться в процессе использования, но, возможно, нет необходимости гарантировать, что оно по-прежнему будет содержать либо его предыдущее, либо все новое содержимое, поэтому вы может решить уничтожить свой существующий массив, прежде чем выделять и назначать новый массив, а затем копировать члены. Вы можете решить не перераспределять, если размер не изменился, а просто переназначить - это приведет к беспорядку новых и старых членов после исключения, но все они будут действительными и безопасными для удаления.

Пожалуйста, убедитесь, что размер соответствует фактическому размеру присоединенного массива всегда! Ваш существующий код допускает эту ошибку, но, в частности, он имеет значение null и 0 после удаления и перед назначением; и он устанавливается на новый новый размер только после назначения нового указателя.

...