Подтвердить что ты не робот

Почему объекты, не названные С++, уничтожаются до завершения блока области видимости?

Следующий код печатает один, два, три. Это верно и верно для всех компиляторов С++?


class Foo
{
      const char* m_name;
public:
      Foo(const char* name) : m_name(name) {}
      ~Foo() { printf("%s\n", m_name); }
};

void main()
{
      Foo foo("three");
      Foo("one");   // un-named object
      printf("two\n");
}
4b9b3361

Ответ 1

Временная переменная живет до конца полного выражения, в котором она была создана. Yours заканчивается точкой с запятой.

Это в 12.2/3:

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

Ваше поведение гарантировано.

Существует два условия, которые, если встречаются, продлевают время жизни временного. Во-первых, это инициализатор для объекта. Во-вторых, когда ссылка привязывается к временному.

Ответ 2

Правила, определяющие время жизни временных объектов, не имеют никакого отношения к понятию сферы. Область действия - это свойство имени, а временные объекты не имеют имен. Другими словами, временные объекты не имеют области видимости.

В большинстве случаев время жизни временного объекта заканчивается в конце полного выражения, создавшего этот объект, что и наблюдалось в вашем эксперименте. Это общее правило, которое имеет некоторые исключения. Главное, что если вы сразу прикрепите ссылку на свой временный объект, время жизни объекта будет расширено, чтобы соответствовать времени жизни ссылки

const Foo &rfoo = Foo("one");

Вышеуказанное временное будет жить до тех пор, пока rfoo живет.

Ответ 3

Объем временного объекта, подобного этому, является только одной строкой. Подумайте об этом, вы больше не сможете ссылаться на него после окончания строки, так почему бы объект не остаться вокруг?

Если бы это было не так, компиляторы не смогли бы оптимизировать временные объекты в вызовах функций.

Ответ 4

Да, это желательно.

Foo foo("three") создает обычный объект, который будет уничтожен при завершении области.

Foo("one") создает временный объект, который уничтожается в конце инструкции [1]. Зачем? Поскольку вы не можете получить к нему доступ после окончания инструкции.

[1] Умышленное упрощение: я должен был указать точку последовательности.

Ответ 5

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

Неименованный объект все равно должен быть помещен в стек и оставаться в стеке до тех пор, пока блок не закончится, и, при ожидании, вытащите его из стека. Построение и разрушение объекта во время одного утверждения бессмысленно. Я хотел бы увидеть один экземпляр/случай, где это действительно полезно. Если он не остается в пределах продолжительности блока, он должен, безусловно, быть ошибкой и должен, как минимум, генерировать предупреждение.