Как его срок службы возвращаемого значения распространяется на область действия вызывающей функции, когда она привязана к константной ссылке в вызывающей функции?

«Если вы вернете значение (а не ссылку) из функции, затем привяжите его к константной ссылке в вызывающей функции, ее время жизни будет расширено до объема вызывающей функции».

Итак: CASE A

const BoundingBox Player::GetBoundingBox(void) { return BoundingBox( &GetBoundingSphere() ); } 

Возвращает значение типа const BoundingBox из функции GetBoundingBox()

вариант I: (привязать его к константной ссылке)

 const BoundingBox& l_Bbox = l_pPlayer->GetBoundingBox(); 

вариант II: (привязать его к копии const)

 const BoundingBox l_Bbox = l_pPlayer->GetBoundingBox(); 

Оба работают нормально, и я не вижу, что объект l_Bbox выходит из области видимости. (Хотя, я понимаю в варианте один, конструктор копирования не вызывается и, следовательно, немного лучше варианта II).

Кроме того, для сравнения я сделал следующие изменения.

CASE B

 BoundingBox Player::GetBoundingBox(void) { return BoundingBox( &GetBoundingSphere() ); } 

с вариантами: I

 BoundingBox& l_Bbox = l_pPlayer->GetBoundingBox(); 

и II:

 BoundingBox l_Bbox = l_pPlayer->GetBoundingBox(); 

Объект l_Bbox прежнему не выходит за пределы области. Как «привязать его к константной ссылке в вызывающей функции, ее время жизни будет расширено до объема вызывающей функции», действительно ли продлить время жизни объекта в области вызывающей функции?

Я что-то пропустил здесь?

Обычно временный объект (например, возвращаемый вызовом функции) имеет время жизни, которое продолжается до конца «охватывающего выражения». Тем не менее, временная привязка к ссылке, как правило, имеет время жизни «продвигается» к времени жизни ссылки (которая может быть или не быть временем жизни вызывающей функции), но есть несколько исключений. Это предусмотрено стандартом в 12.2 / 5 «Временные объекты»:

Временное, к которому привязана ссылка, или временный объект, являющийся полным объектом для подобъекта, связанного с временной привязкой, сохраняется для срока службы ссылки, за исключением случаев, указанных ниже. Временная привязка к ссылочному элементу в ctor-инициализаторе конструктора (12.6.2) сохраняется до тех пор, пока конструктор не выйдет. Временная привязка к эталонному параметру в вызове функции (5.2.2) сохраняется до завершения полного выражения, содержащего вызов.

Для получения дополнительной информации см. Следующее:

  • Постоянный ресурс ссылки C ++ (контейнерный адаптер)
  • GotW # 88: Кандидат на “Наиболее важный const”

Пример, который может помочь визуализировать происходящее:

 #include  #include  class foo { public: foo( std::string const& n) : name(n) { std::cout << "foo ctor - " << name + " created\n"; }; foo( foo const& other) : name( other.name + " copy") { std::cout << "foo copy ctor - " << name + " created\n"; }; ~foo() { std::cout << name + " destroyed\n"; }; std::string getname() const { return name; }; foo getcopy() const { return foo( *this); }; private: std::string name; }; std::ostream& operator<<( std::ostream& strm, foo const& f) { strm << f.getname(); return strm; } int main() { foo x( "x"); std::cout << x.getcopy() << std::endl; std::cout << "note that the temp has already been destroyed\n\n\n"; foo const& ref( x.getcopy()); std::cout << ref << std::endl; std::cout << "the temp won't be deleted until after this...\n\n"; std::cout << "note that the temp has *not* been destroyed yet...\n\n"; } 

Что отображает:

 foo ctor - x created foo copy ctor - x copy created x copy x copy destroyed note that the temp has already been destroyed foo copy ctor - x copy created x copy the temp won't be deleted until after this... note that the temp has *not* been destroyed yet... x copy destroyed x destroyed 

Во-первых, время жизни временного объекта распространяется на время жизни ссылки на const, которая привязана к нему, а не «в объем вызывающей функции» (хотя, возможно, это то, что вы имели в виду под этой странной формулировкой «область вызывающей функции») , Это то, что иллюстрирует ваш CASE A , где вы привязываете ссылку const к временному. Временное продолжает жить до тех пор, пока эта ссылка живет. Когда ссылка заканчивается на всю жизнь, временный объект также уничтожается.

Во-вторых, ваш CASE B просто плохо сформирован, не компилируется. А именно,

 BoundingBox& l_Bbox = l_pPlayer->GetBoundingBox(); 

является незаконным. В C ++ запрещено использовать неконстантную ссылку на временную. Если ваш компилятор разрешает это, это должен быть quirk / extension вашего компилятора, который имеет мало общего с языком C ++.

Дело в том, что при возврате по значению значение копируется в переменную, которую вы назначаете результат функции. (так же, как вы сказали, вызывается конструктор копирования ). Нет продления жизни, вы просто создаете совершенно новый объект.

При возврате по ссылке под капотом вы просто передаете указатель на переменную, определенную в функции. Таким образом, новый объект не создается, вы просто ссылаетесь на него вне функции. В этом случае время жизни функции-внутри переменной увеличивается.

Обычно, если вы возвращаете объект по значению из функции, указанный объект будет уничтожен при завершении выражения присваивания:

 myclass X = getX(); // after copy constructor, the returned value is destroyed // (but you still hold a copy in X) 

В описанном случае возвращаемое значение будет уничтожено позже, что позволит вам использовать его:

 const myclass& X = getX(); cout << Xa << endl; // still can access the returned value, it's not destroyed 
  • Как найти утечку памяти Java
  • что использует MemoryFile в android
  • Как обращаться с realloc при сбое из-за памяти?
  • Насколько опасно доступ к массиву за пределами границ?
  • AngularJS - $ destroy удаляет прослушиватели событий?
  • Слабые справочные преимущества
  • Каков максимальный объем оперативной памяти, которую может использовать приложение?
  • утечка памяти? почему java.lang.ref.Finalizer есть столько памяти
  • Будет ли `char` всегда всегда - всегда иметь 8 бит?
  • Что такое «внутренний адрес» на Java?
  • Поиск диапазона адресов сегмента данных
  • Давайте будем гением компьютера.