Время жизни ссылки относительно ее цели - PullRequest
6 голосов
/ 15 февраля 2012

Чтобы остановить аргумент, идущий в комментариях ответа, который я недавно дал , я хотел бы получить конструктивные ответы на следующие вопросы:

  1. Является ливремя жизни ссылки отличается от объекта, на который она ссылается?Является ли ссылка просто псевдонимом для своей цели?
  2. Может ли ссылка пережить свою цель в правильно сформированной программе, не приводя к неопределенному поведению?
  3. Можно ли сделать ссылку для ссылки на новуюобъект, если хранилище, выделенное для исходного объекта, используется повторно?
  4. Показывает ли приведенный ниже код вышеупомянутые пункты без вызова неопределенного поведения?

Пример кода Ben Voigt и упрощенный (запустите его на ideone.com ):

#include <iostream>
#include <new>

struct something
{
    int i;
};

int main(void)
{
    char buffer[sizeof (something) + 40];
    something* p = new (buffer) something;
    p->i = 11;
    int& outlives = p->i;
    std::cout << outlives << "\n";
    p->~something(); // p->i dies with its parent object
    new (p) char[40]; // memory is reused, lifetime of *p (and p->i) is so done
    new (&outlives) int(13);
    std::cout << outlives << "\n"; // but reference is still alive and well
                                   // and useful, because strict aliasing was respected
}

Ответы [ 2 ]

10 голосов
/ 15 февраля 2012

Отличается ли время жизни ссылки от объекта, к которому она относится?Является ли ссылка просто псевдонимом для своей цели?

Ссылка имеет собственное время жизни:

int x = 0;
{
   int& r = x;
}      // r dies now
x = 5; // x is still alive

Ссылка на const дополнительно может продлить срок жизни своейрефери:

int foo() { return 0; }
const int& r = foo();   // note, this is *not* a reference to a local variable
cout << r;              // valid; the lifetime of the result of foo() is extended

хотя это не без предостережений:

Ссылка на const только продлевает время жизни временного объекта, если ссылка является a) локальной и b) связаннойк prvalue, оценка которого создает указанный временный объект.(Так что это не работает для членов или локальных ссылок, которые связаны с xvalues.) Кроме того, неконстантные ссылки на rvalue продлевают время жизни точно таким же образом. [@ FredOverflow]


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

Конечно, если вы его не используете.


Можно ли сделать ссылку на новый объект, если хранилище, выделенное для исходного объекта, используется повторно?

Да, при некоторых условиях:

[C++11: 3.8/7]: Если после окончания срока службы объекта и до повторного использования или освобождения хранилища, которое занимал объект, новыйобъект создается в месте хранения, которое занимал исходный объект, указатель, который указывал на исходный объект, ссылка, которая ссылалась на исходный объект, или имя исходного объекта, будет автоматически ссылаться на новый объект и, по истечении времени жизнинового объекта, может использоваться для управления новым объектом, если:

  • хранилище для нового объекта точно перекрывает место хранения, котороеоригинальный объект занят, и
  • новый объект того же типа, что и исходный объект (игнорируя квалификаторы cv верхнего уровня), а
  • тип исходного объекта не является константными, если тип класса, не содержит ни одного нестатического члена данных, тип которого является константным или ссылочным типом, и
  • исходный объект был наиболее производным объектом (1.8) типаT и новый объект является наиболее производным объектом типа T (то есть они не являются подобъектами базового класса).

Показывает ли приведенный ниже код вышебаллы без вызова неопределенного поведения?

Tl; др.

5 голосов
/ 15 февраля 2012
  1. Да. Например, локальные нестатические ссылки имеют автоматический срок хранения и соответствующее время жизни и могут ссылаться на объекты с более длительным сроком службы.

  2. Да, висячие ссылки являются примером. Пока такие ссылки не используются ни в каких выражениях, когда они становятся висячими, они в порядке.

  3. В п. 3 есть специальное правило, касающееся этого случая. Имена объектов, указатели и ссылки автоматически ссылаются на новый объект, который повторно использует хранилище в ограниченных условиях. Я считаю, что это в конце 3.8. Кто-то, у кого есть спецификация, пожалуйста, заполните правильную ссылку здесь.

...