• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:コンストラクタ・デストラクタ)

コンストラクタ・デストラクタについての質問

このQ&Aのポイント
  • C++言語でのコンストラクタ・デストラクタの使い方について質問です。
  • コンストラクタはオブジェクトが生成されたときに自動的に呼び出される関数であり、デストラクタはオブジェクトが破棄されるときに自動的に呼び出される関数です。
  • コンストラクタでは、オブジェクトの初期化を行うことができます。一方、デストラクタでは、オブジェクトが破棄されるときに必要な後片付けを行うことができます。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

この例だとデストラクターでやる処理は何もないですね。 このクラスから生成されたオブジェクトが消えるときに、消し残したものはできませんので。 たとえば、このクラスの中でnewなどでほかにメモリーを確保している場合、ネットワークの接続をしている場合は、このクラスが消えるときに明示的にそれらの終了処理を書いておかないとそれらのリソースが残るので、デストラクターでの処理が必要になります。 たとえば、 #include<iostream> using namespace std; class Sample { private: int* n; public: void Show(); Sample(); ~Sample(); }; void Sample::Show() { cout << n[0] << endl; } Sample::Sample() { n = new int[1]; // メモリーを動的に確保 for (int i = 0; i < 1; i++) { n[i] = 0; } std::cout << "コンストラクタが呼び出されました" << std::endl; } Sample::~Sample() { delete [] n; // デストラクタで確保したメモリーを解放 std::cout << "デストラクタが呼び出されました" << endl; } int main() { Sample sample; sample.Show(); return 0; } ただ、今時はSTLやスマートポインターを使ってプログラムを書くのがC++では普通だと思いますので、デストラクターで明示的に何かの処理を書くのは珍しくなってきているかもしれません。メンバー変数をvectorやstring、スマートポインターにしてあるとそれらのデストラクターがちゃんとメモリーを解放してくれますし、メモリー周りのバグを減らすためにそういう書き方をするほうが推奨だと思いますので。

tty215
質問者

お礼

hanabutako様へ 質問時に提示したソースコードは、ごちゃごちゃしていたコメントを消して、自分好みに変数名を少し変えただけで処理的には何もいじってなく、ほぼ丸々コピーした状態のものです。 実際に使っている例ではなく、単に書き方を説明しているだけなのかなと思えてきました。 説明の書いてあるページには、newや、他の方にご回答頂いた例のファイルの入出力等の実際に使っている例はなく理解するには難しいものでしたが、提示したソースコードを修正して頂いたおかげで簡潔で分かりやすかったです。 ありがとうございました。

その他の回答 (2)

  • unacyo
  • ベストアンサー率51% (35/68)
回答No.3

コンストラクタはクラスのインスタンスが発生した際に呼び出されます。 主にメンバ変数の初期化に使います。また、初期化時に行いたい処理も書けます。例えば、ミューテックスやセマフォハンドルの生成とか、クラスをのサブルーチンで共通で使うファイルを開くとか。 逆にデストラクタは、インスタンスが消滅する際に呼び出されます。 使っていたハンドルが閉じてなかったら閉じるとか、開いてあるファイルを閉じるとか。 コンストラクタはインスタンスの生成で呼ばれますから、newした時や、newしない変数定義に呼ばれます。 void test() { Sample sam; //samのインスタンス発生なので、コンストラクタ呼び出し Sample* pSam; //pSamのインスタンスはまだ発生してないから、コンストラクタは呼び出さない sam.Show(); pSam = new Sample(); //pSamのインスタンス発生なので、コンストラクタ呼び出し pSam->Show(); delete pSam; //pSamのインスタンス消滅なので、デストラクタ呼び出し return; //samのインスタンス消滅なので、デストラクタ呼び出し }

tty215
質問者

お礼

unacyo様へ ミューテックス、セマフォハンドルの生成・・・例を挙げて頂けたのはありがたいのですが、調べてもよく分かりませんでした。 これらは、メモしておいて今後、理解したいと思います。すみません。 初期化を行うことと呼び出しのタイミングは理解しました。 ありがとうございました。

回答No.1

コンストラクタには前準備(初期化)、デストラクタには後始末を書きます。 たとえば: class testfile { FILE* fp; public: textfile(const char* fname) { fp = fopen(fname,"r"); } ~textfile() { fclose(fp); } ... };

tty215
質問者

お礼

episteme様へ int型の変数を定義するだけじゃデストラクタは必要がないみたいですね。 私の見た例では、提示したソースコードのようにint型の変数を1つ定義してあるだけだったので、理解に苦しみましたが、他の例を挙げてもらえたおかげで理解できたと思います。 ファイルの入出力でコンストラクタとデストラクタを使うのですね。 C言語もやったことはありますが、確かに開いたファイルは閉じろと言われてたのを思い出しました。 こういう前準備と後始末の一連の動作をコンストラクタとデストラクタの関数で行うと、なるほどと思いました。 ありがとうございました。