Контрольный список для написания конструктора копирования и оператора присваивания в C++
пожалуйста, напишите список задач, которые конструктор копирования и оператор назначения должны сделать в C++, чтобы сохранить безопасность исключений, избежать утечек памяти и т. д.
4 ответов
сначала убедитесь, что вам действительно нужна поддержка копирования. В большинстве случаев это не так, и, таким образом, отключение обоих-это путь.
иногда вам все равно нужно будет обеспечить дублирование класса из полиморфной иерархии, в этом случае: отключить оператор присваивания, написать (защищено?) скопируйте конструктор и предоставьте функцию virtual clone ().
в противном случае, в случае, если вы пишете класс значений, вы возвращаетесь в землю ортогонального канонического Форма Коплиена. Если у вас есть член, который нельзя скопировать тривиально, вам нужно предоставить конструктор копирования, деструктор, оператор присваивания и конструктор по умолчанию. Это правило можно уточнить, см., например:закон Большой Двойки
Я бы также рекомендовал взглянуть на C++ FAQ относительно операторов назначения, и идиома копирования и замены и GOTW.
версии, созданные компилятором, работают в большинстве ситуаций.
вам нужно немного подумать о проблеме, когда ваш объект содержит необработанный указатель (аргумент для отсутствия необработанных указателей). Итак, у вас есть необработанный указатель, второй вопрос: у вас есть указатель (он удаляется вами)? Если да, то вам нужно будет применить правило 4.
владение более чем 1 необработанным указателем становится все труднее делать правильно (увеличение сложности не линейный либо [но это наблюдательно, и у меня нет реальной статистики, чтобы поддержать это утверждение]). Поэтому, если у вас более 1 необработанного указателя, подумайте об обертывании каждого в своем собственном классе (некоторая форма интеллектуального указателя).
Правило 4: Если объект является владельцем необработанного указателя, вам нужно определить следующие 4 члена, чтобы убедиться, что вы правильно управляете памятью:
- конструктор
- Конструктор Копирования
- назначение Оператор
- деструктор
Как вы определяете это будет зависеть от ситуации. Но вещи, чтобы следить за:
- конструкция по умолчанию: установите указатель на NULL
- конструктор копирования: используйте ideum Copy and Swap для предоставления "сильной гарантии исключения"
- оператор присваивания: Проверьте назначение для self
- деструктор: защитите от исключений, распространяющихся из деструктора.
попробуйте прочитать это.
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;
}