Копия temp уничтожается, как любая другая временная переменная, после вычисления выражения, в котором она участвует.
- здесь копирующий конструктор, создающий val, получит в качестве аргумента временную переменную (в общем случае, копию temp). Эта переменная будет уничтожена сразу после выполнения конструктора.
Можно ещё взять такие примеры:
void foo(A param){
// ...
}
void foo2(A& param){
//...
}
A func1(){
return A();
}
int main() {
A temp = func1();
foo(func1());
foo2(func1());
}
можешь добавить отладочный вывод и посмотреть, что будет
Есть одна тонкость: компилятор может оптимизировать создание временных объектов: если у тебя уже есть временная temp на стеке, то вторая может не создаваться. Скажем, есть такой код:
class Test
{
public:
Test(){}
const Test& operator=(const Test& val){ return *this; }
Test(const Test& val){}
~Test(){}
};
Test foo()
{
Test test;
return test;
}
int main()
{
Test val;
val = foo();
return 0;
}
то в результате сначала создаётся Test val, затем вызывается функция и создаётся временный объект test, а на выходе из функции происходит вызов оператора копирования из этого временного объекта в val. Итого, на стеке создаётся только 2 объекта.
При возврате по ссылке никакого копирования объекта не происходит - именно потому что ссылка - это только указатель на объект, но не сам объект. Разумеется, сама ссылка, если это потребуется, будет копироваться.
Если возвращать значение - то будет копироваться значение (с поправкой на оптимизацию, которую может применить компилятор).