お世話になります。
現在、Visual Studio 2005にてMFCのC++のプログラムを作成しているのですが、そこでメモリの使用容量について疑問に感じた点があったのでこちらで、質問させて頂きました。
お聞きしたい内容は
あるクラス1内で別のクラス2を宣言する際に、メンバ変数としてそのクラス2を宣言し、クラス1のコンストラクタでnewでメモリを確保し、デスクリタでdeleteする方法と、その都度クラス2の変数または関数が必要なときにnewでメモリを確保して、deleteで開放する方法とでは、メモリの確保等で違いがなにかありますでしょうか?
また、クラス2をクラス1,クラス3で使用する場合には、クラス1,クラス3でそれぞれクラス2のオブジェクトを宣言するのと、クラス1でクラス2のオブジェクトを宣言し、そのオブジェクトをクラス3でexternするのではどちらの方がメモリの使用等からよい方法なのでしょうか?
今までほとんどメモリを気にせずにプログラムを作っていた為、メモリの使用の点ではほとんど無知な為、変な質問なのかもしれませんが、ご存知の方がいらっしゃいましたら、ご回答をお願い致します。
開発環境は
Widows CE 6.0
Visual Studio 2005
です。
No.3
- 回答日時:
>どちらの方がメモリの使用等からよい方法なのでしょうか?
"等"という言葉があったのでツッコミを入れさせていただきます。
メモリの使用だけに限定されないと解釈しています。
まず、何度も何度もnewを繰り返すと”メモリの断片化(フラグメント)"が
起きる恐れがあります。
http://yougo.ascii.jp/caltar/%E3%83%95%E3%83%A9% …
最近のPCであればメモリを十分に積んでいるので
1) 1MByte new
2) 1MByte delete
3) 100kByte new
4) 100kByte delete
5)1MByte new
6)1Mbyte delete
をするよりは
最初から1MByteをnewもしくはstaticで確保して、使いまわすほうが
好ましいと思われます。
もちろん3)と4)の間では900kByteも無駄が生じることは
百も承知ですが
2GByteの物理メモリで900kByte気にしてもしゃーない
という”富豪プログラミング"です。
あと
>クラス1のコンストラクタでnewでメモリを確保し、デスクリタでdeleteする方法
この場合、クラス1にクラス2の"ポインタ"をもつということになりますね
>クラス1,クラス3でそれぞれクラス2のオブジェクトを宣言する
この場合、クラス2のオブジェクトをクラス1(および3)が抱え込む形ですね。
この2つのパターンにはメモリ以外に重要な違いがあります。
それは前者(ポインタ)の場合は"前方宣言"で済ますことが可能ということです。
前方宣言を使うと、クラス1のコンパイルにクラス2の情報は不要になります。
クラス2の実装を変更してもクラス1はコンパイルしなおさなくて済みます。
ことは、ビルド時間の長短の問題だけではありません。
クラス2はクラス1に影響を与えず、まったく自由に変更できるということは
クラス2はそれと機能面で互換性のある2aや2b...と自由に交換可能に
なるのです。
これは、複雑なプログラムを組む時に非常に大きなメリットとなります。
以上、メモリの瞬間・瞬間の利用効率以外の
長期的視点からみてみました。
以上の視点とメモリを極力無駄にしない努力を
時には天秤にかけ
どちらを優先するか判断してみてください。
丁寧なご回答ありがとうございます。
メモリのnewとdeleteを繰り返すと、フラグメントが発生するのですか。。それは初めて聞きました、参考にさせて頂きます。
ということは、その都度のメモリの使用のみを考えて、あるクラスの各関数内で、ローカル変数として、別のクラスのオブジェクトのnew.deleteを繰り返してメモリを確保するよりも、長期的にみてあるクラスのグローバル変数として他のクラスのオブジェクトを宣言し、コンストラクタでnew,デストラクタでdelteした方がよいとも考えられるということですね。
また、教えて頂いたクラスのオブジェクトの前者、後者の違いですが、あるクラスで別のクラスのオブジェクトを宣言するときは、ポインタとして呼び出す方が、利便性があるということですね。
ご回答ありがとうございます。
No.2ベストアンサー
- 回答日時:
その都度、オブジェクトを生成して済むのであれば、静的メンバ関数にできないか検討してみてはどうでしょうか?
静的メンバ関数にできるのであれば、オブジェクトを生成する必要がなくなりますから、メモリの使用量はゼロになります。
その都度クラス1,クラス3で呼ばれるクラス2の関数を静的関数にしてみたらいい、ということでしょうか?
そうすれば、確かにメモリの使用はなくなりますよね。
その方法で考えてみます!!
No.1
- 回答日時:
クラスのインスタンスがメモリー上に実在するのは
クラスのコンストラクタが実行されてインスタンス
が生成されてから、そのインスタンスがデストラクタで
破棄されるまでで、これをクラスの寿命といいます。
つまり生きているクラスは全てメモリ上に存在するわけです。
以上の理屈より、ご質問の件は自明ですね(^^)/。
ということはクラス1のメンバ変数にクラス2のインスタンスを指定し、クラス1のコンストラクタでnewでメモリを確保すると、クラス1のデストラクタが呼ばれるまで常にクラス2のインスタンス分のメモリが確保され続けてしまうということですね?
逆に、その都度new,deleteを呼ぶことでインスタンス分のメモリの確保・開放を繰り返しているということですか。
だとしたら、面倒でも何度も繰り返しインスタンスを作成したほうがメモリの面ではいいということですね。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
UMLのクラス図はmain()も含むん...
-
修学旅行での演芸大会の出し物...
-
EclipseでJSPのコンパイルエラー
-
どこからも呼ばれていない無意...
-
java eclipse 型に解決できません
-
string formatについて
-
委員長になったのですが、指示...
-
main()を持つクラスが2つ以上...
-
A・B・Cクラスとは?
-
eclipse でクラスに色
-
複数のクラスで共通した関数を...
-
遺伝的アルゴリズムによる繰り...
-
dllと同じプロジェクトにする方法
-
DIVの中の<a>について
-
クラスのプロパティに構造体を...
-
同じクラスにならない確率を教...
-
同じパッケージ、クラス名が含...
-
重複エラーを解決するには
-
基本情報技術者試験のJava問題...
-
eclipeでクラス作成ができない
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
配列の重複する値とその個数を...
-
どこからも呼ばれていない無意...
-
java eclipse 型に解決できません
-
「天声人語」をインターネット...
-
main()を持つクラスが2つ以上...
-
1 つのヘッダファイルに複数の...
-
IPアドレスのクラスAを取得して...
-
同一パッケージにあるクラスが...
-
同じクラスにならない確率を教...
-
重複エラーを解決するには
-
共通で使う関数を集めたクラス...
-
3年間同じクラスになる確率
-
複数のクラスで共通した関数を...
-
同じパッケージ、クラス名が含...
-
A・B・Cクラスとは?
-
自作のクラスファイルがインポ...
-
ATLとMFCの違いは何でしょうか?
-
eclipse でクラスに色
-
コンボボックスのマウスホイー...
-
UMLのクラス図はmain()も含むん...
おすすめ情報