Рассмотрим следующий код, имеющий дело с константными ссылками:
const int & func (const int &x)
{
return x;
}
struct Foo {
Foo (const int &x)
: m_x(x) {}
const int & getX ()
{ return m_x; }
const int &m_x;
};
Я хотел бы знать, какие, если таковые имеются, из следующего позволено:
int x = func(int(7));
int y = Foo(int(7)).getX();
Есть ли гарантия, что временный int
Объект все еще существует до того, как он используется назначением или getX
?.
ОБНОВИТЬПохоже, это безопасно, но почему именно?
Рассмотрим крайний случай, в котором вместо ссылки хранится указатель:
struct Foo {
Foo (const int &x)
: m_x(&x) {}
const int & getX ()
{ return *m_x; }
const int *m_x;
};
int y = Foo(int(7)).getX();
Кажется, что если бы случай 1) был правильным, это не сработало бы. Но если бы случай 2) был верным, это было бы.
Оба безопасны, потому что вы копируете значения в x
а также y
, Временные значения действительны до конца полного выражения.
4) Есть два контекста, в которых временные
другая точка, чем конец полного выражения. Первый контекст
когда конструктор по умолчанию вызывается для инициализации элемента
массив. Если конструктор имеет один или несколько аргументов по умолчанию, любой
временные файлы, созданные в выражениях аргументов по умолчанию, уничтожаются
сразу после возврата из конструктора.5) Второй контекст
когда ссылка связана с временным. Временный, к которому
ссылка привязана или временная, которая является полным объектом
подобъект, к которому привязана ссылка, сохраняется в течение всей жизни
ссылка кроме как указано ниже. Временная привязка к
элемент ссылки в конструкторе ctor-initializer (12.6.2) сохраняется
пока конструктор не выйдет. Временная привязка к ссылке
Параметр в вызове функции (5.2.2) сохраняется до завершения
полное выражение, содержащее вызов. Временная привязка к
возвращаемое значение в операторе возврата функции (6.6.3) сохраняется до
функция выходит. Во всех этих случаях временные
оценка выражения, инициализирующего ссылку, кроме
временные, к которым привязана ссылка, уничтожаются на
конец полного выражения, в котором они созданы и в
обратный порядок завершения их строительства. Если жизнь
двух или более временных, к которым привязаны ссылки, заканчивается на
В тот же момент, эти временные уничтожены в этот момент в
обратный порядок завершения их строительства. К тому же,
уничтожение временных ссылок, связанных с ссылками, должно
Учет порядка уничтожения объектов со статическими или
длительность автоматического хранения (3.7.1,
3.7.2); то есть, если obj1 является объектом со статической или автоматической длительностью хранения, созданной до создания временного объекта, временный
быть уничтоженным до уничтожения obj1; если obj2 является объектом с
статическая или автоматическая продолжительность хранения, созданная после временной
создан, временный должен быть уничтожен после уничтожения obj2. [
Пример:
class C
{
/ / ...
public :
C();
C(int );
friend C operator +(const C&, const C&);
~C();
};
C obj1 ;
const C& cr = C (16)+ C (23);
C obj2 ;
выражение C (16) + C (23) создает три временных. Первый временный Т1
чтобы сохранить результат выражения C (16), второй временный T2 для
держать результат выражения C (23) и третий временный T3 для
держать результат сложения этих двух выражений.
временный T3 затем привязывается к эталонному кр. Не указано
будет ли T1 или T2 создан первым. На реализации, где T1
созданный до T2, он гарантированно уничтожен до T1.
Временные значения T1 и T2 связаны с эталонными параметрами
Оператор +; эти временные уничтожены в конце полного
выражение, содержащее вызов оператора +. Временный Т3 связан с
ссылка cr уничтожается в конце срока службы cr, то есть при
конец программы. Кроме того, порядок, в котором T3
уничтожено учитывает порядок уничтожения других объектов
со статической продолжительностью хранения. То есть, потому что obj1 построен
до того, как T3 и T3 построены до obj2, гарантируется, что
obj2 уничтожается до T3, и этот T3 уничтожается до obj1.
— конец примера]
Оба в безопасности. Временные могут связываться с const
ссылки и они сохраняются до тех пор, пока не будет выполнено выражение, к которому привязан временный объект. В этом случае вы связываете его с аргументом конструктора, и он действует до закрывающей скобки конструктора.
Аналогичным явлением является использование временного в качестве аргумента функции по умолчанию для const
ссылка:
void foo(const someclass& bla = someclass()); // bind const ref with default constructed someclass