Как можно судить по другим ответам - компилятор может оптимизировать это.
Конкретный пример, сгенерированный с использованием MSVC, чтобы объяснить , как это возможно (как это было задано в одном из комментариев) -
Взять урок -
class AClass
{
public:
AClass( int Data1, int Data2, int Data3 );
int GetData1();
private:
int Data1;
int Data2;
int Data3;
};
При следующей тривиальной реализации -
AClass::AClass( int Data1, int Data2, int Data3 )
{
this->Data1 = Data1;
this->Data2 = Data2;
this->Data3 = Data3;
}
int AClass::GetData1()
{
return Data1;
}
И следующий код вызова -
AClass Func( int Data1, int Data2, int Data3 )
{
return AClass( Data1, Data2, Data3 );
}
int main()
{
AClass TheClass = Func( 10, 20, 30 );
printf( "%d", TheClass.GetData1() );
}
(printf () добавлен только для того, чтобы компилятор не оптимизировал все ...).
В неоптимизированном коде мы ожидаем, что Func () создаст локальный AClass в своем стеке, создаст его там и скопирует в качестве возвращаемой переменной.
Однако сгенерированная сборка действительно выглядит (удаляя ненужные линии) -
_TEXT SEGMENT
___$ReturnUdt$ = 8 ; size = 4
_Data1$ = 12 ; size = 4
_Data2$ = 16 ; size = 4
_Data3$ = 20 ; size = 4
mov eax, DWORD PTR _Data3$[esp-4]
mov ecx, DWORD PTR _Data2$[esp-4]
mov edx, DWORD PTR _Data1$[esp-4]
push esi
mov esi, DWORD PTR ___$ReturnUdt$[esp]
push eax
push ecx
push edx
mov ecx, esi
call ??0AClass@@QAE@HHH@Z ; AClass::AClass
mov eax, esi
pop esi
ret 0
3 функциональные переменные извлекаются из стека и помещаются в eax, ecx и edx.
Еще одно четвертое значение помещается в esi (и передается в ecx).
Конструктор вызывается с 3 параметрами в стеке, а ecx все еще содержит четвертое значение.
Давайте посмотрим на конструктор -
_TEXT SEGMENT
_Data1$ = 8 ; size = 4
_Data2$ = 12 ; size = 4
_Data3$ = 16 ; size = 4
mov edx, DWORD PTR _Data2$[esp-4]
mov eax, ecx
mov ecx, DWORD PTR _Data1$[esp-4]
mov DWORD PTR [eax], ecx
mov ecx, DWORD PTR _Data3$[esp-4]
mov DWORD PTR [eax+4], edx
mov DWORD PTR [eax+8], ecx
ret 12 ; 0000000cH
3 параметра конструктора считываются в смещения eax - eax является копией ecx, четвертого параметра из вызова выше.
Итак, конструктор создает объект, в котором ему сообщается - четвертый параметр Func ().
И, как вы уже догадались, четвертый параметр Func () на самом деле представляет собой единственное место во всей программе, где существует созданный класс AClass. Давайте посмотрим на соответствующую часть main () -
_TEXT SEGMENT
_TheClass$ = -12 ; size = 12
_main PROC
sub esp, 12
push 30
push 20
lea eax, DWORD PTR _TheClass$[esp+20]
push 10
push eax
call ?Func@@YA?AVAClass@@HHH@Z ; Func
12 байтов зарезервированы для класса AClass, и передаются три аргумента функции Func (), а также четвертый - указывающий на эти 12 байтов.
Это конкретный пример с конкретным компилятором. Другие компиляторы делают это по-другому. Но это дух вещей.