Операция присваивания в языке программирования C++ обозначается знаком '='. Как и другие операторы в C++, она может быть перегружена.
Операция присваивания копированием - особый вид операции присваивания, используемый для присваивания объектов одного класса друг другу. Является одним из особых членов-функций и генерируется автоматически компилятором в случае, если нет явного объявления программистом. Код, сгенерированный компилятором, выполняет побитовое копирование.
Операция присваивания копированием отличается от конструктора копирования тем, что должна очищать члены-данные цели присваивания (и правильно обрабатывать самоприсваивание), тогда как конструктор копирования присваивает значения неинициализированным членам-данным. Например:
My_Array first; // инициализация конструктором по умолчанию My_Array second = first; // инициализация конструктором копирования second = first; // присваивание операцией присваивания копированием
В качестве особого случая следует отметить следующий вариант инициализации конструктором копирования:
My_Array second = My_Array(); В этом случае компилятор (например VC2013) сразу же без всяких опций оптимизации выполняет оптимизацию возвращаемого значения (RVO, return value optimization) и конструктор копирования не вызывается.
Перегрузка операции присваивания копированием Когда нужно сделать глубокие копии объектов необходимо также принять во внимание и обработку исключений. Одним из способов избежать ошибки перемещения ресурсов является следующий: Получаем новые ресурсы Освобождаем старые ресурсы Присваиваем объекту значения нового ресурса
class My_Array {
int * array; int count;
public:
My_Array & operator = (const My_Array & other)
if (this != &other) // защита от неправильного самоприсваивания
// 1: выделяем "новую" память и копируем элементы int * new_array = new int[other.count]; std::copy(other.array, other.array + other.count, new_array);
// 2: освобождаем "старую" память delete [] array;
// 3: присваиваем значения в "новой" памяти объекту array = new_array; count = other.count;
// по соглашению всегда возвращаем *this return *this;
...
Тем не менее, если успешный метод обмена доступен для всех членов и класс реализует конструктор копирования и деструктор (согласно Правилу трёх), самым коротким путём реализации присваивания копированием будет следующий способ:
public:
void swap(My_Array & other) // обмен члена-функции (неудачи быть не должно!)
// обмен всех членов (и базовых субобъектов, если возможно) с other std::swap(array, other.array); std::swap(count, other.count);
My_Array & operator = (My_Array other) // Примечание: аргумент передается по значению!
// обмен this с other swap(other);
// по соглашению всегда возвращаем *this return *this;
// other уничтожается, освобождая память
Причина, по которой операция = возвращает My_Array& вместо void, проста. Он разрешён для объединения присваиваний, как например:
array_1 = array_2 = array_3; // значение array_3 присваивается array_2 // затем значение array_2 присваивается array_1
См. также Перегрузка операций Операторы в Си и C++
Ссылки
Категория:Синтаксис C++ Категория:Операции в программировании