クラスのメモリ管理について

このQ&Aのポイント
  • クラスのメモリ管理についての問題解決方法を教えてください。
  • AとBの関係におけるクラスの生成と消去についての疑問を解消してください。
  • クラスのメモリ管理における最適な方法についてお教えください。
回答を見る
  • ベストアンサー

クラスのメモリ管理でこんがらがっています

以下の条件があります。 (1)あるメンバ関数Aが、ライブラリの関数Bを呼ぶ (2)AがBを呼ぶ前に、AはBが使うオブジェクトCを生成する (3)AはBから応答が帰ってきた後、Cを削除する (4)AはCの詳細を知らないので、前方参照を使ってCのポインタを作ってそれを引数で渡す (5)BはAから渡されたCに、いろんなデータをつめていって、最後はAにCを引数で返す (6)Bが知っているCの構造は、一つのクラスにたくさんのクラスが集約されているもの この場合、Cのメモリ管理はAが行うことになると思いますが、実際にCに集約されているたくさんのクラスを生成するのは、Bになります。BがAにCを返すときに、Bが生成したたくさんのクラスは、Bの中できちんと消滅させなければいけないのでしょうか?でもそうすると、肝心のCの中身(データ)が消えてしまうので、意味が無いようにも思えます。それとも、Bではたくさんのクラスを生成しっぱなしでもよくて、Aが最後にきちんと全部消去してしまえばよいのでしょうか?でもそれだと、AはCの構造を知らないので、きちんと消去できない気がします。 こんな感じで、こんがらがっているのですが、どなたか問題なく動作させる方法を教えて下さい。結局、「たくさんのクラス」たちは、Bで消すべきか、Aで消すべきか、どちらでも大丈夫なのか、また、「たくさんのクラス」の中では、Aで消すものも、Bで消すものもあってよいのでしょうか?(実際には、Bの中だけで使用するクラスもあるので、そういうクラスはできればBで消去したいです)

  • aneja
  • お礼率93% (379/405)

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

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

anejaさん、こちらこそすみません。文章把握能力が低いもので。。。 >>自分の経験ですが、クラスCに設定されたメンバのインスタンスはクラスCが管理するのが構成としてすっきりすると思います。 >これは、クラスCのトップ(集約される方)の関数で、集約するクラスを明示的にnewする、という認識で合っていますでしょうか。 すみません。クラスCのトップの関数というのは、クラスCのメンバ関数の1つということでしょうか? もちろん。そういう仕様の関数も良いと思います。initializeという関数で初期化処理をしたり、コンストラクタでインスタンスを生成するであったりと考えられます。 ですが、それだけでなく、外部から設定されたインスタンスでもデストラクタでdeleteするとい管理でもよいと思います。(そうでないと今回の仕様は満たされませんよね?) つまり、関数BでクラスCに集約されるクラスDをnewしてそれをクラスCに設定し、そしてクラスDの値を関数Aで使用した後は、不要となる為、クラスDをdeleteする必要がありますが、関数Aの中で直接クラスDをdeleteするのでは無く、クラスCをdeleteするとクラスCのデストラクタで適宜クラスDをdeleteするという構成がいいのかなと思っています。 ただし、何でもかんでもこの構成が良いかというとそうではないので注意して下さい。クラスCをdeleteしても集約しているインスタンスを解放してはいけない構成の方が良い時もあります。(直ぐに例が思いつきませんが。。。) 今回は、クラスCに集約されたクラスは、クラスCと同じ寿命でよいのかなと思ったので最初に回答したような構成をお薦めしました。 ご存知かもしれませんが、このような構成とする場合は、クラスCのデストラクタではNULLチェックをすることをお忘れなく。。。。

その他の回答 (2)

回答No.2

anejaさんが行いたい処理は以下のような処理でよいのでしょうか? 1.Aメソッド内でクラスCをnewで生成。 2.Cのポインターを引数に取るBメソッドを呼ぶ。 3.Bメソッド内でクラスCに色々値やインスタンスを設定しメソッドの処理終了。 4.Aメソッド内で引数に渡したクラスCのポインターから必要な値を使用する。 上記のような処理を行いたいというのであれば、Aメソッド内ではCのデストラクタ(delete)を呼ぶのみにし、クラスCがデストラクタ内で自分のメンバを全てdeleteするような構成が良いと思います。 自分の経験ですが、クラスCに設定されたメンバのインスタンスはクラスCが管理するのが構成としてすっきりすると思います。 >(実際には、Bの中だけで使用するクラスもあるので、そういうクラスはできればBで消去したいです) Bの中だけで使用するクラスであれば、クラスCに設定する必要が無いように思うのですが、どうでしょうか?(クラスCのメンバとしては不適切なのでは。。。) この回答は、上記のような処理であると仮定した上で成り立っていますので、違うところがありましたらご指摘下さい。

aneja
質問者

お礼

ご回答をいただいていたのに、お礼が遅くなり、大変申し訳ありませんでした。とてもわかりやすいご回答をどうもありがとうございました。 説明が拙くて、すみませんでした。前提条件は、Pkakedashi様の書かれたとおりです。 >自分の経験ですが、クラスCに設定されたメンバのインスタンスはクラスCが管理するのが構成としてすっきりすると思います。 これは、クラスCのトップ(集約される方)の関数で、集約するクラスを明示的にnewする、という認識で合っていますでしょうか。 >Bの中だけで使用するクラスであれば、クラスCに設定する必要が無いように思うのですが、どうでしょうか? そうですね、別クラスにできないか、検討してみます。どうもありがとうごました。

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

ん~, 「メモリ管理」以前にプログラムの構成そのものがこんがらがっているようにも感じるんだけど.... 例えば C 自体を抽象クラスにして, B が使うのは C の導出クラス (のオブジェクト) とすれば, A は C の詳細を知らなくても消せますね. まあ, B の中だけで使用するクラス (のオブジェクト) が C を経由して A に伝えられるのも変だと思う.

aneja
質問者

お礼

早速のご回答、どうもありがとうございました。 識者も交えて検討した結果、こういう構成になりました。 すみません、まだオブジェクト指向の知識がほとんど無いのですが、Cを抽象クラスにして、Cの導出クラス(C'とします)をBで生成するということなのでしょうか。 C'の生死に関わらず、AがCのデストラクタを呼ぶと、C'も消滅するのでしょうか? >まあ, B の中だけで使用するクラス (のオブジェクト) が C を経由して A に伝えられるのも変だと思う. これは、おっしゃる通りと思います。 ですので、Aには必要のないいくつかのクラスは、Bの終了処理時に消去しようと思っています。 メモリ管理的には、問題ないのでしょうか。

関連するQ&A

  • 親クラスから呼ぶ

    Javaで親クラスから子クラスを生成して、子クラスから親クラスのメソッドを呼ぶことが できますか? Cなら関数ポインタで呼ぶことができました。 また、C#ならデリゲートなどを使用して呼べました。 可能であれば小さいサンプルでいいので、教えていただけないでしょうか?

    • ベストアンサー
    • Java
  • android-JNIでクラス配列参照方法について

    androidのJNIで関数引数をクラス配列にした場合、C側ではこのポインタをどのようにすれば取得出来るのでしょうか? 一応GetByteArrayElements()を使用してクラス配列の要素数までは取得できましたが、このクラスのポインタの取得方法が出来ません。 ※クラス配列にある変数をC言語側で参照したいと考えております。 (このクラスはC言語の構造体として扱うようにしています)

  • C++ クラスについて

    クラスについて今勉強しています。 そこで質問なんですが クラスの中にクラスというのは実現可能なのでしょうか? クラスAの中にクラスBとクラスCが入っている状態で、 クラスAの中にある関数XでクラスBやCの関数を呼ぶような処理を目指しています。 またクラスAに宣言されている変数をクラスB,Cの中で変更したりできないでしょうか?

  • 現在のクラスを生成したクラスに渡したい

    親クラスで生成した子クラス(ダイアログ)から親クラス(ダイアログ)の関数などを使えるようにしたいと思っております。 ちなみに継承クラスで親クラスの関数を使うのではなく、親クラスそのもの(ダイアログ表示)を子クラスから変更できるようにしたいです。 (簡単になりますが…)プログラムの構成は以下のようになっており、thisポインタを渡すか所でエラーが起こってしまいます。 ------------------------------------------------ class AAA { BBB *b; void classBBB{ b = new BBB(this); // こういうことがしたいが、できない void fun( int a ); // ダイアログの表示が変更する(予定) }; class BBB { AAA *a; BBB(AAA *pDlg){ a==pDlg; } void fun(){ int b; a->fun(b); } // 親クラスの関数を呼び出したい }; ------------------------------------------------ ただし、class Aとclass Bを生成する上位階層のプログラム構築をすることはなしとします。 ------------------------------------------------ こんな感じ AAA *a = new AAA(); BBB *b = new BBB(a); ------------------------------------------------ どうしてもclass AAAからclass BBB呼び出したいと思ってます。 何か良い解決法があれば、教えていただきたいです。 宜しくお願い致します。

  • C++のクラスについて

    C++を勉強しているC言語経験者です。 C++のクラスについてですが、クラスのメリットとはなんでしょうか?なんだか関数ポインタを持った構造体にしか見えないと言うか・・・(あと隠蔽化機能も持ってるんですね)。私が小規模なプログラムを組んだことしかない為か、クラスの必要性が全くわかりません。クラスは具体的にどう使い、どう役に立つものなのでしょうか? 回答よろしくお願いします。

  • クラスの分割

    画像処理のプログラムを書いているのですが、1つのクラスに必要な変数と関数をぶち込んだため、変数20~、関数20~、2000行くらいのクラスになっています。 このままでは見辛いので、クラスを処理ごとに分割して見易くしたいのですが、各関数でいくつか共通の変数を使用しているため上手く分割ができなくて困っています。 データのみのクラスを継承した子クラスを3つ作ってみたらインスタンスが3つできてしまい意味がありませんでした。 ↓の図に示すようなクラスを作りたいのですが、いくつか質問をさせてください       共通データクラス     /    |    \   子クラスA 子クラスB 子クラスC 1、変数20~、関数20~、2000行くらいのクラスは普通でしょうか?(分割する必要がありますか?) 2、↑の図はクラスの作り方として問題がありますか? 3、2で問題がない場合実現する方法として、仮想継承、関数に共通データのポインタを渡す以外に方法があるかどうか まだまだC++を勉強中で、便利な構造体程度にしか使えていませんが、どなたかご教授お願いします。

  • ポインタ引数をさらにポインタ引数に渡す方法

    ポインタ引数をさらに関数のポインタ引数として設定するには、 どうしたらよいのでしょうか? イメージとしては、 int 関数A(*a *b) { *a = 5; *b =3; 関数B(*a *b) } またポインタ引数の関数内で、 ポインタ指定せずに変数を使えるのでしょうか? int 関数A(*a *b) { a = 5; b =3; 関数B(*a *b) }

  • 基本クラスのポインタで、派生クラスのメンバ関数を呼び出す方法?

    VC++でプログラミングをしています。 A(基本クラス) B(派生クラス) を作成しました。Bは、Aの特別な場合です。 このとき、基本クラスAのポインタから、派生クラスBにのみあるメンバ関数を呼ぶことはできないのでしょうか? 基本クラスAにも同じ名前の関数があれば、仮想関数をオーバーロードすれば呼び出せるようですが、この関数は、基本クラスには不要なので、できれば使わないメンバ関数を基本クラスに書きたくありません。 (純粋仮想関数という方法もあるようですが、) 操作としましては、 Aのポインタ配列 A* a[100]を作成し 特別な場合のみ派生クラスBのメンバ関数だけを実行させたいのです。 派生クラスにのみあるメンバ関数を、Readとします。 for(i=0;i<100;i++){ if(派生クラスBの場合){ a[i]->Read() } } 現状では、コンパイルエラーで、 関数Readは、aのメンバ関数ではありませんとなってしまいます。 以上よろしくお願いします。

  • 同一クラスインスタンス名で別クラスのインスタンス作成方法(C++)

    下記ソース(Java)の処理をするような、C++の実装方法を教えていただきたいです。 【処理内容】 クラスBのインスタンスを保持しており、クラスBのインスタンス名と同一であるクラスAのインスタンス生成 ClassA A_Instance = (ClassA)Class.forName(B_instance.name).newInstance(); 要はクラスインスタンスの名前の求め方がわからないのです。それさえわかれば、newしてクラスポインタを返すメソッドを用意すれば何とかなると考えていますが。 ※C++のAPI一覧はどこにあるのだろうか・・・

  • あるクラスであるかどうかを確認する方法は?

    あるクラスが特定のクラスである事を確認する方法が知りたいです。 例えば下記のようにCクラスがBクラスを継承し、BクラスがAクラスを継承していた場合。 あるメソッドでAクラスの引数を受け取ったが、これがAクラスであるかどうかを判別したいです。(BではなくかつCではない) instanceofを使用し、Cでfalse、Bでfalseと判別する方法以外でありましたらお願いします。 Aクラス ..| ..+--Bクラス ......| ......+--Cクラス

    • ベストアンサー
    • Java