Почему мы используем копирование и обмен при использовании оператора присваивания?

У меня есть вопрос об операторе присваивания при использовании метода копирования и замены.

String & operator = (String s) // the pass-by-value parameter serves as a temporary
{
s.swap (*this); // Non-throwing swap
return *this;
}// Old resources released when destructor of s is called.

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

Тогда какая разница между кодом выше и кодом ниже?

String & operator = (String s) // the pass-by-value parameter serves as a temporary
{
return s;
}

Поскольку у нас есть хороший конструктор копирования, я думаю, что другой объект, s, создается внутри функции operator =.
Итак, какой смысл использовать функцию обмена без броска?

0

Решение

Основное отличие состоит в том, что 2-й operator= не меняет текущий объект (т.е. *this) совсем.

String a, b;
b = a; // b is not changed at all

И обратите внимание на 2-й operator= возвращается s (который будет уничтожен при выходе из функции) по ссылке, так что это будет просто привязанная ссылка.


Чтобы быть более общим, мы используем копия & идиома своп обеспечить надежную гарантию безопасности исключений, которая является чем-то вроде семантики фиксации или отката; Если операция завершается из-за исключения, состояние программы останется неизменным.

String & operator = (String s) // Copy construct s. If exception happens here,
// s won't be constructed,
// and the state of the current object (*this) won't be changed
{
s.swap (*this);             // Use non-throwing swap to commit the change
return *this;               // Non-throwing operation
}
3

Другие решения

Разница в том, что во втором блоке кода вы создаете копию s из String объект, вернуть ссылку на него, а затем копия уничтожается при выходе из области видимости, что приводит к неопределенному поведению вашей программы.

0

Есть несколько основных отличий:

Оператор присваивания должен вернуть *this (и почти всегда так). Это то, что делает возможным назначение цепочек.

String s1, s2, s3;
s1 = s2 = s3; // Now all strings ave the same value.

Вместо этого вы возвращаете ссылку на локальную переменную. Затем он становится висячей ссылкой, поскольку он не указывает на допустимое место в памяти.

Кроме того, оператор присваивания должен изменить назначенный объект, чего не происходит в вашем коде.

И, наконец, зачем вообще нужен неработающий своп? Давайте предположим, что ваш оператор присваивания создает исключение. Каково состояние назначенного объекта после неудачного назначения?

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

Вот где приходит своп. Так как своп никогда не выбрасывает, мы можем быть уверены, что назначенный объект находится в допустимом состоянии. Если перед свопом выдается исключение, объект все еще имеет свое старое значение, а если он был после свопа, то у объекта новое значение.

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector