Почему неименованные объекты C ++ разрушаются до окончания блока области видимости? - PullRequest
16 голосов
/ 19 февраля 2010

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


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");
}

Ответы [ 5 ]

36 голосов
/ 19 февраля 2010

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

Это в 12.2 / 3:

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

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

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

12 голосов
/ 19 февраля 2010

Правила, управляющие временем жизни временных объектов, не имеют ничего общего с понятием scope .Scope является свойством name , а временные объекты не имеют имен.Другими словами, временные объекты не имеют области действия.

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

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

Вышеупомянутый временный объект будет существовать до rfoo живет.

6 голосов
/ 19 февраля 2010

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

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

3 голосов
/ 19 февраля 2010

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

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

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

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

0 голосов
/ 22 февраля 2016

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

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

...