Деструктор C++, как гарантируют, не назовут до конца блока?

В коде C++ ниже, мне гарантируют это ~obj (), деструктор назовут после//выполняется Больше кода? Или компилятору позволяют разрушить объект obj ранее, если он обнаруживает, что он не используется?

{
  SomeObject obj;
  ... // More code
}

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

34
задан Skurmedel 18 January 2010 в 16:43
поделиться

8 ответов

Вы в порядке с этим - это очень часто используемая модель в программировании C ++. Из стандартного раздела C ++ 12.4 / 10 ссылается, когда вызывается деструктор:

для построенного объекта с Автоматическая продолжительность хранения когда блок, в котором объект Созданные выходы

46
ответ дан 27 November 2019 в 16:04
поделиться

Деструктор не будет вызван, пока объект не выйдет из объема.

FAQ C ++ FAQ Lite имеет хороший раздел на DTOR

18
ответ дан 27 November 2019 в 16:04
поделиться

Все ответы здесь адрес, что происходит с именами объектов, но для полноты, вы, вероятно, должны знать правило для временных / анонимных объектов. (например, F (oneObjectStructoructor () или f (некоторыеfunctionSaturnsanObject ()) )

Временные объекты разрушаются как последний шаг в оценке полного выражения (1.9), что (лексически ) Содержит точку, где они были созданы. Это правда, даже если эта оценка заканчивается в том, чтобы выбрасывать исключение. (12,2 / 3 из стандарта ISO C ++ 98)

, которые в основном означает, что временно сгенерированные объекты сохраняются до следующего оператора. , Две исключения предназначены для временных, генерируемых как часть списка инициализации объекта (в этом случае временный пункт уничтожен только после того, как объект полностью построен), и если ссылка сделана во временной (например, const foo и ref = ) ) (в этом случае срок службы объекта является срок службы ссылки).

2
ответ дан 27 November 2019 в 16:04
поделиться

Типичный пример этого, так же, как ваш вопрос - повышение :: scoped_ptr (или подобный std :: auto_ptr):

{
    boost::scoped_ptr< MyClass > pMyClass( new MyClass );

    // code using pMyClass here

} // destruction of MyClass and memory freed
1
ответ дан 27 November 2019 в 16:04
поделиться

Уничтожение в C ++ является детерминированным - это означает, что компилятор не может перемещать этот код вокруг. (Конечно, оптимизация может встроить деструктор, определить, что код деструктора не взаимодействует с // Больше кода и выполняет некоторую инструкцию, но это еще одна проблема)

, если вы не могли зависеть от Разрушетели называются, когда они должны быть вызваны, вы не можете использовать Raii, чтобы захватить замки (или практически любые другие конструкции Raii):

{
    LockClass lock(lockData);
    // More code
} // Lock automatically released.

Кроме того, вы можете зависеть от деструкторов, работающих в обратном порядке, как объекты были построены.

9
ответ дан 27 November 2019 в 16:04
поделиться

Да, он гарантируется.

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

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

На самом деле, языковой стандарт даже не полагается на понятие масштаба , чтобы описать срок службы автоматических объектов (не нужно иметь дело со всеми этими терминологическими слоями). Он только говорит, что объект разрушен на выходе из блока, в котором он определен :)

5
ответ дан 27 November 2019 в 16:04
поделиться

Да, стандарт C ++ имеет очень специфические требования к тому, когда объекты разрушаются (в §12.4 / 10), и в этом случае он не должен быть уничтожен до тех пор, пока все другой код в блоке не закончится выполнение.

3
ответ дан 27 November 2019 в 16:04
поделиться

На самом деле ...

C ++ имеет что-то называемое принципу «как будто». Все Guarentees, сделанные ссылки на все эти ответы, относящиеся к наблюдаемым наблюдаемым поведению . Компилятор разрешено ellude, переупорядочить, добавить и т. Д. Любой вызов функции, если наблюдаемое поведение, как если бы он был выполнен как изначально написан. Это также относится к деструкторам.

Итак, технически, ваше наблюдение является правильным: компилятор - это , разрешено разрушать объект ранее, если он обнаруживает его не используется, и нет наблюдаемых побочных эффектов от деструктор или любая функция это вызывает. Но вы, Гуарен, чтобы не быть в состоянии сказать, что это происходит за пределами отладчика, потому что если бы вы смогли сказать, компилятор больше не сможет это сделать.

Скорее всего, компилятор использует эту силу для того, чтобы сделать что-то полезное, например, полностью эллед тривиальному деструктору, а не фактически перенаправить вызовы деструктора.

Отредактируйте: Кто-то хотел ссылку ... 1,9 / 5, наряду с сноска 4 проекта C ++ 0x (это не новое правило, у меня просто нет C ++ 03 Стандартный удобный. Он также присутствует в стандарте C AFAIK)

1.9 / 5:

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

Сноска 4:

Это положение иногда называют правилом «As - if», потому что реализация свободна игнорировать любые требования этого Международный стандарт до тех пор, пока результат, как будто требование было подчиняться, насколько это может быть определено из наблюдаемое поведение программы. Например, фактическая реализация не должна оценивать часть выражения, если это может Вывод, что его значение не используется, и что побочных эффектов не влияют на наблюдаемое поведение программы.

Мое чтение (и то, что я думал, было общее понимание) было то, что это то, что позволяет свободной рукой компилятора делать все, что она хочет (т. Е., позволяет оптимизацию), если наблюдаемое поведение является то, что исходный письменный источник - в том числе движущийся вокруг деструкторов, не разрушающих объекты вообще, изобретении деструкторов и т. Д.

24
ответ дан 27 November 2019 в 16:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: