16

C++ では、オブジェクトのデストラクタは、オブジェクトが作成されたブロックの "}" を閉じるときに呼び出されますよね? したがって、これは次のことを意味します。

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

次に、ループの 1 回の繰り返しで作成されたオブジェクトのデストラクタが、別のオブジェクトが作成される前にループの最後で呼び出されますよね?

ありがとう。

4

2 に答える 2

26

はい。

しかし、あなたはそれを自分でテストすることができたでしょう. これは、コンパイラが間違いを犯す可能性が低い言語機能です。

#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;
  }
}
于 2012-04-30T17:45:18.667 に答える
8

観察可能な動作は、各反復と呼ばれることです。

ただし、最適化に関する通常のルールは引き続き適用されます。コンパイラがスマートでオブジェクトが単純な場合、コンパイラは、正しい動作を生成する好きなことを何でも実行できます。たとえば、次のようになります。

#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

つまり、展開され、そのデストラクタの兆候はありません (ただし、観察可能な動作は同じです)。

于 2012-04-30T17:54:48.280 に答える