Оператор присваивания (C ++) - Assignment operator (C++)

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

В оператор присваивания копий, часто называемый просто «оператором присваивания», является частным случаем оператора присваивания, в котором источник (правая часть) и пункт назначения (левая сторона) относятся к одному и тому же типу класса. Это один из специальные функции-члены, что означает, что его версия по умолчанию создается компилятором автоматически, если программист не объявляет ее. Версия по умолчанию выполняет поэлементное копирование, где каждый член копируется собственным оператором присваивания копии (который также может быть объявлен программистом или генерирован компилятором).

Оператор присваивания копий отличается от оператора конструктор копирования в том, что он должен очищать элементы данных цели назначения (и правильно обрабатывать самоназначение), тогда как конструктор копирования назначает значения неинициализированным элементам данных.[1] Например:

My_Array первый;           // инициализация конструктором по умолчаниюMy_Array второй(первый);   // инициализация конструктором копированияMy_Array в третьих = первый;   // Также инициализация конструктором копированиявторой = в третьих;           // присваивание с помощью оператора присваивания копии

Возвращаемое значение перегруженного оператора присваивания

Язык позволяет перегруженному оператору присваивания иметь произвольный тип возвращаемого значения (включая пустота). Однако обычно определяется, что оператор возвращает ссылку правопреемнику. Это согласуется с поведением оператора присваивания для встроенных типов (возврат присвоенного значения ) и позволяет использовать вызов оператора как выражение, например, в управляющих операторах или в прикованное задание. Так же Стандартная библиотека C ++ требует такого поведения для некоторых типов, задаваемых пользователем.[2]

Перегрузка оператора присваивания копии

Когда глубокие копии объектов должны быть сделаны, безопасность исключений следует принимать во внимание. Один из способов добиться этого, когда освобождение ресурсов никогда не заканчивается неудачей:

  1. Приобретайте новые ресурсы
  2. Освободите старые ресурсы
  3. Назначьте объекту дескрипторы новых ресурсов
учебный класс My_Array{    int* множество;    int считать;общественный:    My_Array& оператор=(const My_Array& Другой)    {        если (это != &Другой) { // защита от недействительного самоназначения            // 1: выделить новую память и скопировать элементы            int* new_array = новый int[Другой.считать];            стандартное::копировать(Другой.множество, Другой.множество + Другой.считать, new_array);            // 2: освободить старую память            Удалить[] множество;            // 3: присвоить объекту новую память            множество = new_array;            считать = Другой.считать;        }        // по соглашению всегда возвращать * this        возвращаться *это;    }    // ...};

Однако если безошибочный (без броска ) замена доступна для всех подобъектов-членов, и класс предоставляет конструктор копирования и деструктор (что он должен делать в соответствии с правило трех ), наиболее простой способ реализовать присваивание копий выглядит следующим образом:[3]

общественный:    пустота замена(My_Array & Другой) // функция-член подкачки (не должна выходить из строя!)    {        // меняем местами все элементы (и базовый подобъект, если применимо) с другими        с помощью стандартное::замена; // из-за ADL компилятор будет использовать         // настраиваемый своп для членов, если он существует        // возврат к std :: swap        замена(множество, Другой.множество);        замена(считать, Другой.считать);    }    My_Array & оператор = (My_Array Другой) // примечание: аргумент передается по значению!    {        // поменять местами это на другое        замена(Другой);        // по соглашению всегда возвращать * this        возвращаться *это;        // другое уничтожается, освобождая память    }

Распределение между разными классами

C ++ поддерживает назначение между разными классами, как через неявное конструктор копирования и оператор присваивания, если целевой класс экземпляра является предком исходного класса экземпляра:

учебный класс Предок {общественный:    int а;};учебный класс Потомок : общественный Предок {общественный:    int б;};int главный(){    Потомок d;    Предок а(d);    Предок б(d);    а = d;}

Копирование из объектов-предков в объекты-потомки, в результате чего поля потомка могут оставаться неинициализированными, не допускается.

Смотрите также

Рекомендации

  1. ^ Страуструп, Бьярне (2000). Язык программирования C ++ (3-е изд.). Эддисон-Уэсли. п. 244. ISBN  978-0-201-70073-2.
  2. ^ Рабочий проект стандарта языка программирования C ++, раздел 17.6.3.1, таблица 23; http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf
  3. ^ Саттер, Х.; Александреску, А. (Октябрь 2004 г.), Стандарты кодирования C ++, Эддисон-Уэсли, ISBN  0-321-11358-6

внешняя ссылка