0

クラスがC++クラスでデストラクタを定義する必要があるのはいつですか?なぜですか?

C ++でこれを学び始めたばかりで、明確にする必要があります。

4

6 に答える 6

5

動的に割り当てられたメモリを解放するなど、クラスが特別なクリーンアップを行う必要がある場合にのみ、デストラクタを定義する必要があります。

于 2013-07-15T00:45:03.180 に答える
3

動的にメモリを割り当てた場合は、デストラクタを定義する必要があります。経験則として、コンストラクターのいずれかで new を使用する場合、おそらくデストラクタが必要です。自動ストレージでも静的ストレージでもないものは、動的に割り当てられたと見なされます

クリーンアップのカテゴリに該当するものはすべて、たとえばネットワーク接続を閉じるなど、デストラクタに入れるのが適切です

于 2013-07-15T00:47:59.110 に答える
1

他にも理由があるかもしれませんが、私が考えている最初の理由は、クラス属性の一部を明示的に解放する必要があるかもしれないということです。

クラスに 2 つの int 属性があるだけの場合、それらは を呼び出すときにオブジェクトとともに自動的に削除されますdelete myObject。ただし、動的に割り当てられた属性が含まれている場合、それらはオブジェクトとともに解放されないため、デストラクタで明示的に削除する必要があります。

于 2013-07-15T00:49:04.853 に答える
1

デストラクタのデフォルトの動作が希望どおりでない場合にのみ、デストラクタを定義する必要があります。

オブジェクトが破棄されると、カスタム デストラクタを定義するかどうかに関係なく、デストラクタは次のことを行います。

  • 各データ メンバーのデストラクタを呼び出します。
  • 各ベースのデストラクタを呼び出します。

これは、実際にやりたいことのほとんどを処理します。コンストラクターでメモリが割り当てられたときに、カスタム デストラクタを定義するのが一般的でした。

struct A {
    B *b_ptr;

    A() : b_ptr(new B) { }
    ~A() { delete b_ptr; }
};

ただし、標準コンテナーとスマート ポインターを使用している場合、カスタム デストラクタが必要になるケースは比較的少なくなります。たとえば、このようなクラスがある場合

struct A {
    std::unique_ptr<B> b_ptr;

    A() : b_ptr(new B) { }
};

std::unique_ptr が割り当てられたメモリを解放するため、独自のデストラクタを定義する必要はありません。同様に、ここでデストラクタを定義する必要はありません

struct B {
    ifstream input_stream;

    B(const std::string &path) : input_stream(path) { }
};

input_stream、input_stream メンバーが破棄されると自動的に閉じられるためです。

場合によっては、何か特別なことをしなければならない場合もあります。リソースを取得または解放するには、特別な呼び出しが必要です。その場合、デストラクタが必要です。

struct C {
    ResourceHandle resource_handle;
    C() : resource_handle(resouce_manager.acquireResource()) { }
    ~C() { resource_manager.releaseResource(resource_handle); }
};

ただし、多くのクラスで重複する必要がないように、この種の動作をできる限りローカライズする必要があります。たとえば、次のようなクラスを作成したい場合があります。

struct ResourceHolder {
    ResourceHandle resource_handle;
    ResourceHolder() : resource_handle(acquireResource()) { }
    ~ResourceHolder() { releaseResource(resource_handle); }
};

これらのリソースのいずれかを必要とする各クラス内で ResourceHolder を使用するだけで、取得と解放のロジックを再度繰り返す必要がなくなりました。

于 2013-07-15T01:09:16.563 に答える
0

デストラクタは、たとえばコンストラクタで割り当てられたメモリを解放するためだけに使用されるわけではありません。

デストラクタを使用して、 RAII スタイルの機能を実現できます。

これを利用する型の例:

std::fstream開いているファイルを閉じます

std::lock_guardミューテックスのロックを解除します

std::shared_ptr参照カウンターをデクリメントするか、カウンターが 0 の場合はメモリを解放します。

于 2013-07-15T01:12:05.387 に答える
0

デストラクタを定義する必要がある 2 つのインスタンスがあります。

  1. クラスのどこかにリソースを割り当てています。コピーコンストラクターと代入演算子も考慮してください。それらが使用されないようにするためであっても、それらを定義する必要がある可能性があります。
  2. クラスはから派生します。この場合、デストラクタは仮想でなければなりません。その理由は、派生クラスのインスタンスを保持する親クラスへの参照またはポインターを使用して派生クラスが破棄される場合、派生クラスのデストラクタが呼び出されないためです。
于 2013-07-15T01:57:56.983 に答える