4

私は現在、クラスとコンストラクタ/デストラクタについて学ぼうとしています。2 つが何をするかは理解していますが、デストラクタを使用するための実用的なアプリケーションが思いつかないため、デストラクタで苦労しています。

誰でも説明付きの例を提供できますか?

4

6 に答える 6

10

デストラクタは、オブジェクトによって割り当てられたリソースを解放するために使用される特別なメンバー関数です。

最も一般的な例は、クラスのコンストラクターが を使用newし、デストラクタが を使用deleteしてメモリの割り当てを解除する場合です。

class Myclass
{
    int *m_ptr;
    public:
        Myclass():m_ptr(new int)
        {
        }
        ~Myclass()
        {
             delete m_ptr;
        }
        //ToDo: Follow Rule of Three
        //Provide definitions for copy constructor & copy assignment operator as well

};
于 2012-04-25T06:37:31.880 に答える
7

デストラクタはおそらくc++の最も重要な側面であり、リソースを管理し、ハンドルの割り当て解除、ソケットからの切断、DBなどの特別なクリーンアップを処理するコードを追加できるようにします。BjarneStroustupは、これは素晴らしいことの1つでもあると述べています。デストラクタについて:

ポジティブな驚きもありました。最も壮観なのは、リソース管理とエラー処理(例外を使用)に関連する手法でのデストラクタの普及です。デストラクタが良いアイデアであることは知っていましたが、結局のところ、コンストラクタの効果を元に戻す必要がありますが、C++をうまく利用するためにデストラクタがどれほど中心的であるかはわかりませんでした。

元の記事: http: //msdn.microsoft.com/en-us/magazine/cc500572.aspx

また、イディオムRAII(Resource Acquisition Is Initialization)にも不可欠であり、この記事でBjarneによって説明されています: http ://www.artima.com/intv/modern3.html

デストラクタに関するこのC++のFAQを読むと、さらに役立つはずです。

Alsのコードサンプルは良い例だと思います。また別の例であるウィキペディアの記事でコードサンプルを見ることができます。オブジェクトがスコープ外になったとき、または呼び出されたときにデストラクタが呼び出されるという事実deleteは非常に便利です。私が使用しているのは、特定の関数呼び出しにかかる時間を計測するためのタイマーオブジェクトクラスです。

class myTimer
{
  mytimer():startTime( TimeNow() )
  {}
  ~myTimer()
  { 
    printf("time taken :%I64d", TimeNow() - startTime);
  }
private:
  __int64 startTime;
};

だから私のコードではこのようなことをします

myClass::myFunction()
{
  myTimer timer; // initiliases time to Now.

  someOtherFunc();
} // mytimer object is now out of scope and the destructor is called and prints the time it took
于 2012-04-25T06:45:02.790 に答える
2

たとえば、ファイル操作用のクラスがあり、ifstreamこのファイルが自動的に閉じられてクラスのインスタンスが消えるようにしたいとします。デストラクタでファイル ハンドルを閉じます。

于 2012-04-25T06:38:37.640 に答える
1

これらは、動的に割り当てられたオブジェクトの構成がある場合に最も強力になります

linkedListリストへのポインタを保持する構造を作成しているとしlinkedListNodesましょう。最初の要素へのポインタを保持し、最後の要素を1つまたは2つに応じて保持します。

デストラクタでは、リスト内のすべての要素、つまりリスト自体を削除します。

デストラクタをコーディングしないと、リストがスコープ外になるか、リストにdeleteが呼び出されると、それらの要素に割り当てられていたメモリが失われ、システムで再利用できなくなります(特にメモリリークと呼ばれます)。

于 2012-04-25T06:42:53.627 に答える
1

ここで@Alsの答えを拡張します。たとえば、クラスがあります。

class A {
    B* ptrB; // B is another class / struct / internal type
    A() { ptrB = new B(); }
}

int main() {
    A* ptrA = new A();
    // Do something with A
    delete ptrA; // This does not free ptrA->ptrB
}

この問題に対処するには、次のように A でデストラクタを宣言します。

~A() { delete ptrB; } // This is called every time delete is called on
                      // an object of A
于 2012-04-25T06:46:20.450 に答える
1

コンストラクタとデストラクタは、RAII (Resource Allocation Is Initialization) イディオムの非常に重要な要素です。リソース (ファイル、メモリ、ソケット、その他のクラス オブジェクト) の取得をオブジェクトの有効期間にリンクすることは、非常に強力なツールです。通常の実行または例外によってオブジェクトがスコープ外になった場合、オブジェクト デストラクタを呼び出すと、多くの追加のファイナライズ手順でオブジェクトを使用してコードに負担をかけることなく、クラスがリソースを適切にクリーンアップできます。

于 2012-04-25T06:46:44.280 に答える