2008-10-18 8 views
18

Пожалуйста, напишите список задач, конструктор копирования и оператор присваивания нужно сделать в C++, чтобы сохранить безопасность исключений, во избежание утечки памяти и т.д.Контрольный список для написания конструктор копирования и оператор присваивания в C++

ответ

15

Сначала убедитесь, что вам действительно нужно поддерживать копию. Большую часть времени это не так, и, таким образом, отключение обоих - это путь.

Иногда вам необходимо предоставить дублирование в классе из полиморфной иерархии, в этом случае: отключить оператор присваивания, написать конструктор копии (защищенный?) И предоставить функцию virtual clone().

В противном случае, если вы пишете класс ценности, вы вернетесь в землю Ортогональной канонической формы Коплиена. Если у вас есть член, который не может быть тривиально скопирован, вам необходимо предоставить конструктор-копию, деструктор, оператор присваивания и конструктор по умолчанию. Это правило может быть утонченным, смотрите, например: The Law of The Big Two

Я также рекомендую взглянуть на C++ FAQ regarding assignment operators и на copy-and-swap idiom и в GOTW.

-2

Я понятия не имею, о исключение безопасно здесь, но я иду таким образом. Представим себе, что это шаблонная оболочка массива. Надеюсь, это поможет :)

Array(const Array& rhs) 
    { 
     mData = NULL; 
     mSize = rhs.size(); 
     *this = rhs; 
    } 

    Array& operator=(const Array& rhs) 
    { 
     if(this == &rhs) 
     { 
      return *this; 
     } 

     int len = rhs.size(); 

     delete[] mData; 

     mData = new T[len]; 

     for(int i = 0; i < len; ++i) 
     { 
      mData[i] = rhs[i]; 
     } 

     mSize = len; 

     return *this; 
    } 
+0

Этот код не является безопасным исключением. Всегда выделяйте перед выпуском! – 2008-10-18 11:58:43

+0

Нет, это не так. У меня не было проблем с безопасным кодом с исключениями, поэтому у меня не было возможности попрактиковаться. Это одно из вышеперечисленных методов, как правило, вы используете STL-контейнеры. Пожалуйста, разместите свой фрагмент, я хотел бы взглянуть на него. – Nazgob 2008-10-18 12:02:32

+0

В ссылках, которые я предоставил в своем ответе, есть много фрагментов. BTW, тест, препятствующий самоналожению, теперь рассматривается как анти-идиома (теперь, когда исключения лучше понятны) – 2008-10-18 12:17:02

4

Форматы, сгенерированные компилятором, работают в большинстве ситуаций.

Вам нужно подумать немного сложнее о проблеме, когда ваш объект содержит указатель RAW (аргумент для отсутствия указателей RAW). Итак, у вас есть указатель RAW, второй вопрос: у вас есть указатель (он удаляется вами)? Если это так, вам нужно будет применить правило 4.

Владение более чем 1 стрелочником RAW становится все труднее сделать правильно (увеличение сложности не является линейным либо [но это наблюдение, и у меня нет реальной статистики для назад это утверждение вверх]). Поэтому, если у вас есть более 1 указатель RAW, подумайте об обертывании каждого в своем классе (некоторая форма умного указателя).

Правило 4: Если объект является владельцем RAW указателя, то вам необходимо определить следующие 4 пользователей, чтобы убедиться, обрабатывать управление памятью правильно:

  • Конструктора
  • Конструктор копирование
  • Оператор присваивания
  • Destructor

Как вы определяете это будет зависеть от situat ионов. Но вещи, чтобы следить за:

  • По умолчанию Строительство: Установить указатель на NULL
  • Конструктор копирования: Используйте Копировать и своп Ideum предоставить в «гарантии Strong Exception»
  • оператора
  • Назначение: Проверка для назначения to self
  • Деструктор: защита от исключений, распространяющихся из деструктора.