Давайте посмотрим, что происходит в вашей основной функции:
int main() {
Foo bar = newObj();
Здесь мы просто создаем экземпляр Foo
и инициализируем его возвращаемым значением newObj()
.Здесь не вызывается деструктор из-за copy elision : чтобы суммировать очень быстро, вместо копирования / перемещения obj
в bar
и последующей деструкции obj
, obj
напрямую создается в bar
Хранилище.
bar.a = 5;
Здесь нечего сказать.Мы просто меняем значение bar.a
на 5.
bar = newObj();
Здесь bar
присваивается копия 1 , возвращаемое значение newObj()
, затем временный объект, созданныйэтот вызов функции уничтожен 2 , это первый Goodbye
.На данный момент bar.a
больше не 5
, но что бы ни было в a
.
}
Конце main()
, локальные переменные уничтожаются, включая bar
, этовторой Goodbye
, который не печатает 5
из-за предыдущего назначения.
1 Здесь не происходит перемещение из-за пользовательского деструктора, нет назначения перемещенияоператор неявно объявлен.
2 Как упоминалось в комментариях YSC, обратите внимание, что этот вызов деструктора имеет неопределенное поведение, потому что он обращается к a
, который не инициализирован в этой точке.Присвоение bar
временному объекту и, в частности, присваивание a
как его части, также имеет неопределенное поведение по тем же причинам.