0

クラスを作成しました。Andrew Koenig と Barbara E. Moo による教科書 Accelerated C++ によると、

デストラクタの作業は、オブジェクトがなくなるたびに実行する必要があるクリーンアップを実行することです。通常、このクリーンアップには、コンストラクターが割り当てたメモリなどのリソースの解放が含まれます。

私はデストラクタを書こうとしていますが、そこに浮かんでいるすべてのコードに混乱しています。このような単純なデコンストラクタが使用さ~MyIntArray() {}れることもあれば、{}.

中かっこの間に物を置くかどうかの背後にあるルールは何ですか? リスト、配列、ベクトル、中かっこの間に配置する必要があるポインターなどの単なるコンテナーですか (これらはコード例で見られるものです)。

編集:必要な場合に備えて、これは私のクラスです

class msgInfo
{
public:
    msgInfo();
    msgInfo(int, int, int, std::string, std::list<int>);

private:
    int source_id;
    int dest_id;
    int priority;
    std::string payload;
    std::list<int> nodePath;
};
4

8 に答える 8

3

ルール 1:

C++03の 3 の規則または C++11 の 5 の規則。

クラスにユーザー定義のコピー コンストラクターまたはコピー代入演算子が必要な場合は、ユーザー定義のデストラクターが必要になる可能性が高くなります。

これら 3 つのいずれかが必要になるのはいつですか?

  • クラスが動的にポインター メンバーを割り当て、別のインスタンス メンバーとは別にそれぞれの有効期間を維持する必要がある場合。例:char *メンバー。
  • リソースを管理する場合。例: オープン ファイル ハンドル、ミューテックス ロックなど。

ルール 2:

クラスが派生に使用されることを意図しており、オブジェクトのポリモーフィックな削除が必要な場合は、Base クラスのデストラクタを としてマークする必要がありますvirtual

于 2013-03-27T07:38:51.370 に答える
2

リソースを動的に割り当てた場合 (new など)、デストラクタでそれらを解放 (削除) したい場合、すべてのメンバーが動的に割り当てられないため、デストラクタは空 (または非) にすることができます。存在する)。

言及する価値のあるもう1つの注意点は、デストラクタを実装することになり、誰かがクラスを継承することを計画している場合は、それを仮想にする必要があるということです。

于 2013-03-27T07:38:22.187 に答える
1

明示的な必要性がない場合でも、C++ プログラムでデストラクタを提供することは、優れたプログラミング手法です。あなたのコードでは、動的なメモリ割り当てがない可能性があるため、提供されるデストラクタにはコードが含まれていません ~MyIntArray() {}

C++ での 3 の規則に関するウィキペディアの記事もお読みください。

http://en.wikipedia.org/wiki/Rule_of_three_(C%2B%2B_programming)

于 2013-03-27T07:38:24.373 に答える
1

クラスには、デストラクタで処理する必要があるリソースがありません。各タイプは組み込み ( `int) or handles its own resources (std::string ,std::list`) のいずれかです。したがって、独自のデストラクタを実装する必要はありません。コンパイラは、空のブレースと同等のものを提供します。

クラスに、動的に割り当てられたオブジェクト、ソケットへのハンドルまたは接続、データベース、参照カウントなどを処理する必要があるリソースがある場合は、独自に実装する必要があります。

空のデストラクタを実装することが理にかなっている状況の 1 つは、多態的に派生させて使用することを意図したクラスがある場合です。この場合、仮想デストラクタが必要です (それについては多くの SO 投稿があります)。処理するリソースがない場合に派生型がそれ自体を実装する必要がないように、空の実装を提供するのが一般的です。

virtual ~Foo() {}
于 2013-03-27T07:38:34.707 に答える
1

デストラクタを指定しない場合は、コンパイラがデストラクタを提供します。この自動生成デストラクタは、クラスのすべてのデータ メンバのデストラクタを正しく呼び出しますpayload

それ以上のことをする必要がない場合は、明示的にデストラクタを提供する必要はありません。または、空のものでも同様に機能します。

一方、コンストラクターがリソースを割り当てる場合 (データベースへの接続など) は、通常、そのリソースを解放する (データベースから切断するなど) ために、デストラクタにコードを追加する必要があります。これは、リソース リークを防ぐために使用される標準の C++ イディオムです。

于 2013-03-27T07:38:42.150 に答える
0

このようなクラスには、重要なデストラクタ (「中かっこで囲まれたもの」を含むもの) は必要ありません。

デストラクタでは、「手動で」割り当てたリソースを解放する必要があります。例えば:

  • new/new[]コンストラクタにあり、デストラクタでこのメモリを解放する必要がある場合
  • コンストラクタでファイルを開いた場合は、デストラクタで閉じます
  • コンストラクタでミューテックスをロックした場合は、デストラクタでロックを解除します

このようなもの。

また、オブジェクトが破棄されるときに、追加のロジックを実装する必要がある場合があります。何をしようとしているかによって異なります。

于 2013-03-27T07:39:46.143 に答える
0

デストラクタの定義は、私が知っている限り、または懸念している限り、常に次のようにする必要があります。

~msgInfo() { /* free stuff */ }

一方、コンストラクタは次のようになります。

msgInfo(): m_var1(0), m_var2("Initialize") { /* further initialization */ }

との間:{あるのは、メンバー変数の初期化です。

デストラクタでは、クラス内の他の場所に動的に割り当てられたものはすべて解放する必要があります。したがって、おそらくオブジェクト:に対して行う必要があるため、表記法は適切ではありません。delete

于 2013-03-27T07:41:00.173 に答える
0

あなたのコードでは、動的メモリ割り当てがない場合があるため、デストラクタを提供する必要はありません。

于 2013-03-27T09:02:11.263 に答える