Можете ли вы гарантировать порядок деструкторов, когда объекты объявляются в стеке? - PullRequest
19 голосов
/ 07 августа 2009

У меня есть код, который управляет блокировкой / разблокировкой мьютекса в зависимости от области действия:

void PerformLogin()
{
    ScopeLock < Lock > LoginLock( &m_LoginLock );

    doLoginCommand();

    ScopeLock < SharedMemoryBase > MemoryLock( &m_SharedMemory );

    doStoreLogin();

    ...
}

Могу ли я гарантировать, что MemoryLock будет уничтожено до LoginLock?

Ответы [ 5 ]

37 голосов
/ 07 августа 2009

Да, это так. В любой конкретной области локальные объекты уничтожаются в порядке, обратном тому, как они были построены.

11 голосов
/ 07 августа 2009

Добавление к ответу Нейла.

Подумайте, верно ли обратное, то есть вы не можете предсказать порядок деструкторов для объявленных в стеке переменных. Это сделало бы практически невозможным использование зависимых типов значений в стеке. Рассмотрим

void Foo() {
  Type1 t1;
  Type2 t2(&t1);
  ...
}

Если бы C ++ не гарантировал упорядочение деструктора, прямой код, подобный этому, был бы невероятно небезопасным, потому что было бы возможно уничтожить t1 до запуска деструктора t2. Следовательно, вы не можете гарантировать, что деструктор t2 работал с допустимым значением t1.

11 голосов
/ 07 августа 2009

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

3 голосов
/ 08 августа 2009

На вопрос уже был дан ответ, но я хотел бы добавить, что у меня обычно есть привычка писать что-то вроде этого:

void PerformLogin()
{
    ScopeLock < Lock > LoginLock( &m_LoginLock );
    doLoginCommand();

    {
        ScopeLock < SharedMemoryBase > MemoryLock( &m_SharedMemory );
        doStoreLogin();
        ...
    }
}

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

Я всегда пишу лишние круглые скобки в чем-то вроде (a && b) || c, и я нахожу этот вопрос довольно похожим.

(*): Конечно, вы также можете использовать комментарий.

0 голосов
/ 14 января 2011

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

...