Подтвердить что ты не робот

Контрольный список для написания конструктора копий и оператора присваивания в С++

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

4b9b3361

Ответ 1

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

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

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

Я также рекомендую взглянуть на часто задаваемые вопросы по С++ относительно операторов присваивания и на идиома копирования и замены и GOTW.

Ответ 2

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

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

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

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

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

Как вы определяете, они будут зависеть от ситуаций. Но нужно следить за:

  • Конструкция по умолчанию: установите указатель на NULL
  • Копировать конструктор: используйте Copy и Swap ideum, чтобы предоставить "Сильную гарантию отсутствия"
  • Оператор присваивания: проверьте назначение на себя
  • Деструктор: защита от исключений, распространяющихся из деструктора.

Ответ 4

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

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;
    }