Мое прочтение вашего вопроса говорит о том, что вы путаетесь с временными затратами времени больше, чем что-либо еще. Я думаю, это поможет, если вы поставите пару cout
s, как показано ниже:
struct Test{
int i;
Test(int ii):i(ii){ std::cout << "new object\n"; }
Test& operator=(int ii){
i = ii;
return *this;
}
Test operator+(const Test& rhs){
return Test(i + rhs.i);
}
void non_const_function(){
i *= i;
}
~Test() { std::cout << "deleting ...\n"; }
};
Теперь бегите, и вы сможете увидеть, что именно происходит под капотами. (Проверка стиля: не проверять самостоятельное назначение - не очень хорошая вещь.)
Это также поможет, если вы ссылаетесь на стандарт: он обсуждает что-то похожее на то, что вы опубликовали:
12.2 Временные объекты
4 Существует два контекста, в которых временные уничтожаются в другой точке, чем конец фуллэкспрессии. Первый контекст - это когда конструктор по умолчанию вызывается для инициализации элемента массива. Если конструктор имеет один или несколько аргументов по умолчанию, уничтожение каждого временного объекта, созданного в выражении аргумента по умолчанию, выполняется до создания следующего элемента массива, если таковой имеется.
5 Второй контекст - это когда ссылка связана с временным. Временный объект, к которому привязана ссылка, или временный объект, являющийся полным объектом подобъекта, к которому привязана ссылка, сохраняется в течение всего времени существования ссылки, за исключением случаев, указанных ниже. Временная привязка к элементу ссылки в конструкторе ctor-initializer (12.6.2) сохраняется до выхода из конструктора. Временная привязка к ссылочному параметру в вызове функции (5.2.2) сохраняется до завершения полного выражения, содержащего вызов. Временная привязка к возвращенному значению в операторе возврата функции (6.6.3) сохраняется до выхода из функции. Временная привязка к ссылке в новом инициализаторе (5.3.4) сохраняется до завершения
полное выражение, содержащее новый инициализатор.
struct S { int mi; const std::pair<int,int>& mp; };
S a { 1, {2,3} };
S* p = new S{ 1, {2,3} }; // Creates dangling reference
[Примечание: это может привести к появлению зависшей ссылки, и реализации рекомендуется
выдайте предупреждение в таком случае. - конец примечания] Уничтожение временного, чье время жизни не продлевается путем привязки к ссылке, упорядочивается до уничтожения каждого временного, который построен ранее в том же полном выражении. Если время жизни двух или более временных объектов, к которым привязаны ссылки, заканчивается в одной и той же точке, эти временные объекты уничтожаются в этой точке в порядке, обратном завершению их построения. Кроме того, при уничтожении временных ссылок, связанных с ссылками, следует учитывать порядок уничтожения объектов со статическим, потоковым или автоматическим сроком хранения (3.7.1, 3.7.2, 3.7.3); то есть, если obj1
является объектом с той же продолжительностью хранения, что и временное хранилище, и созданным до создания временного, временное должно быть уничтожено до уничтожения obj1
; если obj2
является объектом с такой же продолжительностью хранения, что и временное, и созданным после создания временного, временное должно быть уничтожено после уничтожения obj2
. Пример:
struct S {
S();
S(int);
friend S operator+(const S&, const S&);
~S();
};
S obj1;
const S& cr = S(16)+S(23);
S obj2;
выражение C(16)+C(23)
создает три временных. Первый временный T1
для хранения результата выражения C(16)
, второй временный T2
для хранения результата выражения C(23)
и третий временный T3
для хранения результата сложения этих два выражения. Временный T3
затем привязывается к ссылке cr
. Не указано, будет ли сначала создан T1
или T2
. В реализации, где T1
создается до T2
, гарантируется, что T2
будет уничтожено до T1
. Временные значения T1
и T2
привязаны к опорным параметрам operator+
; эти временные символы уничтожаются в конце полного выражения, содержащего вызов operator+
. Временный T3
, связанный с ссылкой cr
, уничтожается в конце срока службы cr
,
тотесть, в конце программы. Кроме того, порядок уничтожения T3
учитывает порядок уничтожения других объектов со статической продолжительностью хранения. То есть, поскольку obj1
создается до T3
, а T3
создается до obj2
, гарантируется, что obj2
будет уничтожено до T3
, а T3
уничтожено до obj1
.