Это лучше всего можно объяснить на небольшом примере:
Live on Coliru
struct A {
A(int a) { cout << "A::ctor\n"; } //ctor
A(const A& a) { cout << "A::copy\n"; } //copy ctor
A& operator=(const A& a) { cout << "A::operator=\n"; } //copy assign
};
int main()
{
A a(2); //calls constructor
a = A(10); //calls constructor first, then copy assignment
}
Вывод:
A::ctor
A::ctor
A::operator
Приведенное выше говорит само за себя. В первом случае вызывается только конструктор. Для второго сначала вызывается конструктор, а затем копируется присваивание.
SomeClass не реализован operator=
.
Это не имеет значения, потому что компилятор может создайте его для вас. Если вы удалите его явно, приведенный выше код не скомпилируется. Однако, если у вас определен конструктор перемещения, он будет использоваться:
(я настоятельно рекомендую вам прочитать Правило трех / пяти / нуля и понять его. Оно входит в число лучших 5 вещей в C ++, которые вы должны знать.)
A& operator=(const A& a) = delete; //copy assign deleted
A& operator=(A&& other) { cout << "move assigned\n"; } //move assign available
Теперь вы, возможно, задаетесь вопросом, что произойдет, если будут доступны и копирование, и перемещение. Давайте посмотрим:
A a(2); //ctor
a = A(10); //ctor + move assign
A b(3); //ctor
b = a; // copy assign only
a = std::move(b); // move assign
Для a = A(10)
move assign вызывается, потому что A(10)
- это rvalue того же типа, что и то, что находится слева от =
.
В последнем случае a = std::move(b);
мы явно приводим b
к rvalue (да, это то, что делает std::move()
). Поскольку теперь это rvalue, вызывается присвоение перемещения.
Пространство, выделенное для x, просто перезаписывается, как если бы оно было недавно выделенной памятью, или что именно происходит?
- Сначала создается временное:
A(10)
. Разумеется, для него будет выделено пространство. - Его результат затем присваивается
a
, поэтому предыдущие значения в a
перезаписываются - деструктор для временного будет вызываться
И когда это хорошая идея?
Это хорошая идея, когда она вам нужна, это зависит от вашего сценария использования. Как правило, я бы рекомендовал не копировать assign без надобности.