Контрольный список для написания конструктора копирования и оператора присваивания в 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;
    }