Возврат объекта из функции

190
28 ноября 2018, 16:50

Вопрос по поводу вот такого случая:

some_obj foo() {
    some_obj s;
    return s;
}
int main() {
    auto a = foo();
    return 0;
}

Знаю, что за все время вызовется только один конструктор и один деструктор, а конструкторы копирования не вызываются. Но хочу узнать почему так возможно? Объект создается прямо рядом со стэком 'main'? Если перед созданием возвращаемое значения создать еще один объект то что тогда? Как все это выглядить на стэке?

Answer 1

Посмотрел у себя где объект создаётся. У меня в main оставляется память в стеке для возвращаемого объекта, а сама функция foo при создании переменной s не пачкается с памятью , а берёт место в стеке у main.

//> g++ -std=c++11 tempobj.cpp 
# include <iostream>
class some_obj {
public :
some_obj(){std::cout<<"some_obj():this="<<std::hex<< this <<std::dec<< std::endl;}
~some_obj(){std::cout<<"~some_obj():this="<<std::hex<< this <<std::dec<< std::endl;}
} ;
some_obj foo() {
  volatile  bool  stacktop  ;
  std::cout<<"foo:stacktop="<<std::hex<<(void*) & stacktop<<std::dec << std::endl;
    some_obj s;
    some_obj slocal;
    return s;}
int main() {
  volatile  bool  stacktop  ;
  std::cout<<"main:stacktop="<<std::hex<<(void*) & stacktop<<std::dec << std::endl;
    auto a = foo();
  std::cout<<"main:a="<<std::hex<<(void*) & a<<std::dec << std::endl;  
    return 0;}

Результат:

main:stacktop=0x7fff83ef0dff
foo:stacktop=0x7fff83ef0dcf
some_obj():this=0x7fff83ef0dfe
some_obj():this=0x7fff83ef0dce
~some_obj():this=0x7fff83ef0dce
main:a=0x7fff83ef0dfe
~some_obj():this=0x7fff83ef0dfe

Переменная slocal хранится в стеке foo, а s в main.

Answer 2

Детали реализации есть детали реализации. Например, компилятор может транслировать такой код в некое подобие

some_obj foo(some_obj &result) {
  // Конструируем `result` вместо исходного `s`
}
int main() {
  some_obj a; 
  // Здесь объект `a` не конструируется в `main`, 
  // а просто выделяется сырая память правильного размера
  foo(a);
  // Деструктируем `a` как обычно
}

И не надо никакого "рядом со стэком 'main'".

READ ALSO
Получение значения из шейдера

Получение значения из шейдера

Пусть имеется простые шейдера, образующие шейдерную программу:

173
C/C++, Visual Studio, Юникод/Многобайтовые кодировки

C/C++, Visual Studio, Юникод/Многобайтовые кодировки

В настройках проекта Visual Studio можно выбирать набор используемых символовОбычно там есть два пункта:

194
Запись значения из QSpinBox в переменную int

Запись значения из QSpinBox в переменную int

Пытаюсь записать значение из QSpinBox в переменную int с помощью слота:

187