2

C++ は、スタックに割り当てられたオブジェクトに対してデストラクタが呼び出されることをどのように保証しますか? 次のように動的メモリを割り当てると、デストラクタ関数 (またはそのポインタ) はどうなりますか。

class MyClass {
public:

  ~MyClass()
  {
    std::cout<<"Destructor called."<<std::endl;
  }  

  MyClass()
  {
    std::cout<<"Constructor called."<<std::endl;
  }

};

....................................................................

//Limit scope for example
{
  MyClass instance;
}

コンストラクタとデストラクタの両方が呼び出されます。何が起きてる?

4

6 に答える 6

7

コンパイラは、オブジェクトのデストラクタへの呼び出しを適切な位置に挿入します。

于 2009-09-01T13:02:08.947 に答える
4

これがなぜなのか不思議に思わないでしょう。

{
  int i;
}

i自動的に作成および破棄しますよね?C++ は、組み込み型と同じように動作する型を作成できるようにするために多くのことを行います。組み込み型と同様に、C++ (たとえば、Java や C# 以外) では、これは

{
  MyClass instance;
}

nullまたは実際のオブジェクトにバインドされる可能性のある参照を定義するだけではありません。実際のオブジェクトを作成します。

オブジェクトの作成は 2 つのステップで行われます。最初に (スコープに入ると) 生のメモリが提供されます。次に (オブジェクト定義が検出されると) コンストラクターが呼び出されます。組み込み型の場合、コンストラクターは呼び出されません。組み込み変数を初期化しない場合、値はランダムになります。(実際には、ステップ #1 で提供されたメモリのビット パターンが何であれです。) オブジェクトの削除も 2 つのステップで行われます。ランタイムシステム。

(通常、スタック変数のメモリの提供と削除は、レジスタのインクリメント/デクリメントと同じくらい安価であることに注意してください。)

于 2009-09-01T13:58:22.450 に答える
3

コンストラクターは、変数が作成されるとすぐに呼び出されます。デストラクタに関しては、コンパイラはスコープの最後にデストラクタを呼び出すコードを発行します。この感覚をつかむには、「goto」または switch/case 構成を使用してスコープを途中で終了し、コンパイラが文句を言うのを見てください。

于 2009-09-01T13:00:28.397 に答える
3

はい、コンストラクタとデストラクタの両方が呼び出されます。さらに重要なこと:

{
 MyClass instance;
 throw "exception";
}

この例では、デストラクタも呼び出されます。そのため、私は常にオブジェクトをスタックに割り当てることを好みます (または、少なくとも動的割り当てをスタック割り当てガーディアンでラップします)。

于 2009-09-01T13:49:22.900 に答える
1

オブジェクトを作成しているため、コンストラクターが呼び出されます。そのオブジェクトをクリーンアップするため、デストラクタが呼び出されます。C++ では、スタック上で宣言されたオブジェクトは、それを含むスコープがなくなると自動的にクリーンアップされることに注意してください。

于 2009-09-01T13:00:03.030 に答える
0

まあ、コンストラクタの直後にデストラクタを呼び出していませんでした。
プログラムを終了しようとしているときにそれを呼び出します。

int main() {
    MyClass obj;
    cout<<"testing....1"<<endl;
    cout<<"testing....2"<<endl;
    return 0;
}

答え:

Constructor called.
testing....1
testing....2
Destructor called.
于 2009-11-05T07:12:05.063 に答える