• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:C++の解放時の動作)

C++の解放時の動作

このQ&Aのポイント
  • C++の解放時の動作について疑問があるため質問させていただきます。
  • 簡略ですが、上記を走らせた場合、インスタンスは正しく解放されるのでしょうか?一応デストラクタは動作しますが、実際のところ、子クラス分のデータが解放されない気がします。
  • ネット上のサンプルでこういった例を時々目にしますが、この方法は問題ないのでしょうか?

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

  • ベストアンサー
  • qwertfk
  • ベストアンサー率67% (55/81)
回答No.4

おそらく、懸念されているとおりの問題が発生します。 > 一応デストラクタは動作しますが、実際のところ、子クラス分のデータが解放されない気がします。 とかかれていますが、実際にはその反対で、データは開放されるが、子クラス分のデストラクタが呼び出されません。 下記のコードを実行するとわかりやすいと思います。 class Super{ public: ~Super(){cout << "s" << endl;} }; class Child : public Super{ public: ~Child(){cout << "c" << endl;} }; int main(int argc, char* argv[]) { cout << "A:" << endl; Super* a = new Child(); delete a; cout << endl; cout << "B:" << endl; Child* b = new Child(); delete b; return 0; } ちょっと乱暴な解釈ですが、基本的には継承がある場合はデストラクタは仮想関数にしたほうが良いです。 class Super{ public: virtual ~Super(){cout << "s" << endl;} }; class Child : public Super{ public: virtual ~Child(){cout << "c" << endl;} };

ClickHere
質問者

お礼

ご回答、ありがとございます。 VC++2008上で実行すると、子クラスのデストラクタは実行されていませんが、 メモリリークも検出されませんでした。 デストラクタ実行→メモリ領域解放 の動作順だとばかり考えていたので、いまいちピンときませんね…。 ちゃんと解放されているのなら、いいのですが…。

すると、全ての回答が全文表示されます。

その他の回答 (6)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.7

ふと思ったんだけど, #5 へのお礼中 「親クラスにデストラクタを定義しないと子クラスのデストラクタが正しく動作しない」 ってどういう意味なんだろう. どんな処理系でどう「正しく動作しない」のかが気になる.

ClickHere
質問者

お礼

>「親クラスにデストラクタを定義しないと子クラスのデストラクタが正しく動作しない」ってどういう意味なんだろう 仮想関数にしない場合、以下の様にしないと継承した際に~Super()が呼ばれない状態です。 class Super{ public: ~Super(){} }; >どんな処理系でどう「正しく動作しない」のかが気になる. x86系PCのWindows上で実行しています。多分、機種依存の問題ではなく、根本的な言語の仕様と思われます。

すると、全ての回答が全文表示されます。
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.6

もしかして delete a ; // sizeof(SUPER)分のメモリが解放される delete (Child *)a ; // sizeof(Child)分のメモリが解放される とか考えてます? それとも delete a ; // SUPERの private:float x, y, z;は解放されるけど // Childの private: int a, b, c;が解放されない delete (Child *)a ; // Childの private: int a, b, c;も解放される とか考えてますか? 普通、deleteは、newで確保した分を解放します。 C言語のmallocでどんなサイズを指定しても、freeに指定するのはポインタだけですよね? 今回の例では、どちらもデストラクタを呼ぶ意味が無いので、問題ありません。

ClickHere
質問者

お礼

ご回答、ありがとうございます。 >もしかして >delete a ; // sizeof(SUPER)分のメモリが解放される >delete (Child *)a ; // sizeof(Child)分のメモリが解放される >とか考えてます? 大体そんなことを考えていました。 malloc()とdelete、newとfree()の組み合わせが禁止されているので、 もしかしたら、型で決めているのでは?という心配をしていました。 デストラクタが動作しない以外は問題がないのですね。 勉強になりました。

すると、全ての回答が全文表示されます。
  • wormhole
  • ベストアンサー率28% (1626/5665)
回答No.5

>ちょっと乱暴な解釈ですが、基本的には継承がある場合はデストラクタは仮想関数にしたほうが良いです。 ただ質問者さんのあげられてる例のSuperとChildはデストラクタは定義しなくてもデフォルトデストラクタで十分なんですよね。

ClickHere
質問者

お礼

ご回答、ありがとうございます。 >ただ質問者さんのあげられてる例のSuperとChildはデストラクタは定義しなくてもデフォルトデストラクタ>で十分なんですよね。 親クラスにデストラクタを定義しないと子クラスのデストラクタが正しく動作しないので 定義しています。子クラスは完全に蛇足でした。 確認したところ、確かに仮想関数にすると、両方のデストラクタが動作しました。

すると、全ての回答が全文表示されます。
回答No.3

> この方法は問題ないのでしょうか? 「この方法」とはどの部分を指していますか?

ClickHere
質問者

お礼

ご回答、ありがとうございます。 子クラスのインスタンスを親クラスの型としてdeleteすることです。 よろしくお願いします。

すると、全ての回答が全文表示されます。
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

この場合各メンバがデストラクタを持たないので, Super にしろ Child にしろそもそもデストラクタを作る必要がありません. なので「意味的にはおかしいけどこの場合に関して言えば結果的に『正しく』動作する」というところかな. 相変わらず「データが解放される」が何を意味するのかは分からん.

ClickHere
質問者

お礼

ご回答、ありがとうございます。 >相変わらず「データが解放される」が何を意味するのかは分からん newでインスタンス化される際に、内部で確保するメモリ領域のつもりです。

すると、全ての回答が全文表示されます。
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

「データが解放される」とはどういう意味でしょうか? 「子クラス分のデータが解放されない気がします」とありますが, 親クラス分のデータが「解放される」かどうかについては全く気にならないんでしょうか? 気にならないとしたら ・解放される ・解放されない のどちらだと考えているのですか? そしてその理由は?

ClickHere
質問者

お礼

ご回答、ありがとうございます。 質問内容にミスがありましたので、補足させていただきました。 それではよろしくお願いいたします。

ClickHere
質問者

補足

ご回答、ありがとうございます。 Super *p = new Child; とした際に、 delete p; と delete (Child*)p; の動作に違いが出るか?という意味合いのつもりです。 補足ですが、質問内容に A *a = new Child; とありましたが、 Super *a = new Child; のミスでした。 それでは、よろしくお願いいたします。

すると、全ての回答が全文表示されます。

関連するQ&A