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

С++. Если объект объявлен в цикле, его деструктор называется в конце цикла?

В С++ деструктор объекта вызывается при закрытии "}" для блока, в котором он был создан, правильно? Таким образом, это означает, что если у меня есть:

while(some_condition)
{
    SomeClass some_object;
    some_object.someFunction();
    some_variable = some_object.some_member;
}

Затем деструктор для объекта, созданного на одной итерации цикла, будет вызываться в конце цикла до создания другого объекта, правильно?

Спасибо.

4b9b3361

Ответ 1

Да.

Но вы могли бы проверить его самостоятельно. Это языковая функция, что компиляторы вряд ли ошибаются.

#include <iostream>

struct S {
  S() { std::cout << "S::S()\n"; }
  ~S() { std::cout << "S::~S()\n"; }
};

int main () {
  int i = 10;
  while(i--) {
    S s;
  }
}

Ответ 2

Наблюдаемое поведение состоит в том, что он вызывает каждую итерацию.

Обычные правила об оптимизации все еще применяются. Если компилятор умный, а объект простой, то компилятор может делать все, что ему нравится, что все еще создает правильное поведение, например:

#include <iostream>

struct foo {
  int i;
  foo() : i (-1) {}
  ~foo() { i = 1; }
};

int main() {
  int i = 10;
  while (--i) {
    foo f;
    std::cout << f.i;
  }
}

Скомпилируется:

.Ltmp5:
        .cfi_def_cfa_register %rbp
        movl    $_ZSt4cout, %edi
        movl    $-1, %esi
        callq   _ZNSolsEi
        movl    $_ZSt4cout, %edi
        movl    $-1, %esi
        callq   _ZNSolsEi
        movl    $_ZSt4cout, %edi
        movl    $-1, %esi
        callq   _ZNSolsEi
        movl    $_ZSt4cout, %edi
        movl    $-1, %esi
        callq   _ZNSolsEi
        movl    $_ZSt4cout, %edi
        movl    $-1, %esi
        callq   _ZNSolsEi
        movl    $_ZSt4cout, %edi
        movl    $-1, %esi
        callq   _ZNSolsEi
        movl    $_ZSt4cout, %edi
        movl    $-1, %esi
        callq   _ZNSolsEi
        movl    $_ZSt4cout, %edi
        movl    $-1, %esi
        callq   _ZNSolsEi
        movl    $_ZSt4cout, %edi
        movl    $-1, %esi
        callq   _ZNSolsEi
        xorl    %eax, %eax
        popq    %rbp
        ret

т.е. разворачивается и нет признаков этого деструктора (хотя наблюдаемое поведение остается тем же).