Контрольный список для написания конструктора копирования и оператора присваивания на C ++
-
03-07-2019 - |
Вопрос
Пожалуйста, напишите список задач, которые необходимо выполнить конструктору копирования и оператору присваивания в C ++, чтобы обеспечить безопасность исключений, избежать утечек памяти и т.д.
Решение
Сначала убедитесь, что вам действительно нужна поддержка копирования. В большинстве случаев это не так, и, таким образом, отключение обоих - это путь.
Иногда вам все равно необходимо обеспечить дублирование класса из полиморфной иерархии, в этом случае: отключите оператор присваивания, напишите (защищенный?) конструктор копирования и предоставьте виртуальную функцию clone (). р>
В противном случае, если вы пишете класс значений, вы возвращаетесь в страну Ортогональной Канонической Формы Коплиена. Если у вас есть элемент, который не может быть просто скопирован, вам потребуется предоставить конструктор копирования, деструктор, оператор присваивания и конструктор по умолчанию. Это правило можно уточнить, см., Например: Закон Большой Двое р>
Я также рекомендовал бы ознакомиться с часто задаваемыми вопросами C ++ относительно операторов присваивания и в идиоме копирования и обмена и на GOTW .
Другие советы
Сгенерированные компилятором версии работают в большинстве ситуаций.
Вам нужно немного внимательнее подумать о проблеме, когда ваш объект содержит НЕОБРАБОТАННЫЙ указатель (аргумент в пользу отсутствия необработанных указателей).Итак, у вас есть НЕОБРАБОТАННЫЙ указатель, второй вопрос заключается в том, являетесь ли вы владельцем указателя (вы его удаляете)?Если это так, то вам нужно будет применить правило 4.
Владение более чем 1 необработанным указателем становится все более трудным для корректной работы (увеличение сложности также не является линейным [но это наблюдение, и у меня нет реальной статистики, подтверждающей это утверждение]).Поэтому, если у вас есть более 1 необработанного указателя, подумайте о том, чтобы обернуть каждый в свой собственный класс (некоторая форма интеллектуального указателя).
Правило 4:Если объект является владельцем НЕОБРАБОТАННОГО указателя, то вам необходимо определить следующие 4 элемента, чтобы убедиться, что вы правильно управляете памятью:
- Конструктор
- Конструктор копирования
- Оператор присваивания
- Деструктор
То, как вы их определите, будет зависеть от конкретной ситуации.Но есть вещи, на которые следует обратить внимание:
- Конструкция по умолчанию:Установить указатель в значение NULL
- Конструктор копирования:Используйте идею копирования и подкачки для обеспечения "Надежной гарантии исключения".
- Оператор присваивания:Проверьте, нет ли присвоения самому себе
- Деструктор:Защищайтесь от исключений, распространяющихся из деструктора.
попробуйте прочитать это.
http://www.icu-project.org/docs /papers/cpp_report/the_anatomy_of_the_assignment_operator.html р>
очень хороший анализ оператора присваивания
Я понятия не имею об исключениях, но я иду этим путем. Давайте представим, что это шаблонная оболочка массива. Надеюсь, это поможет:)
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;
}