Почему оператор присваивания делает что-то отличное от соответствующего конструктора? - PullRequest
4 голосов
/ 14 мая 2010

Я читал какой-то буст-код и наткнулся на это:

inline sparse_vector &assign_temporary(sparse_vector &v) {
    swap(v);
    return *this;
}
template<class AE>
    inline sparse_vector &operator=(const sparse_vector<AE> &ae) {
        self_type temporary(ae);
        return assign_temporary(temporary);
    }

Кажется, что все конструкторы отображаются в операторы присваивания. Отлично. Но почему C ++ когда-либо заставлял их делать разные вещи? Все, что я могу думать, это scoped_ptr?

Ответы [ 3 ]

6 голосов
/ 14 мая 2010

почему C ++ когда-либо заставлял их делать разные вещи?

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

Кстати, в самые ранние времена C ++, T a(b); фактически был определен как T a; a = b;, но это оказалось неэффективным, поэтому появился конструктор копирования.

2 голосов
/ 14 мая 2010

Обратите внимание, что имя «assign_teilitary» указывает, что назначение происходит от объекта, который является временным и, следовательно, может быть уничтожен в процессе назначения. Оператор присваивания принимает некоторый обычный объект, который вы, возможно, захотите использовать позже, поэтому его нельзя уничтожить во время присваивания. В этом Boost-коде «assign_teven» является синонимом оператора присваивания rvalue , в то время как оператор присваивания, который вы показали выше, является стандартным оператором присвоения ссылок const (lvalue), поэтому вы ожидаете такого рода несоответствие между ними.

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

1 голос
/ 14 мая 2010

По той причине, что некоторым классам иногда нельзя разрешать присваивать или даже копировать. Например, используя RAII, вы можете создать класс мьютекса, который открывает блокировку, а затем закрывает блокировку по истечении срока действия. Если вам было разрешено копировать или назначать такой класс, вы могли бы пропустить его за пределами области действия функции. Это может привести к плохим вещам в руках плохих людей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...