【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集

お世話になります。
現在、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
です。

A 回答 (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...と自由に交換可能に
なるのです。
これは、複雑なプログラムを組む時に非常に大きなメリットとなります。

以上、メモリの瞬間・瞬間の利用効率以外の
長期的視点からみてみました。

以上の視点とメモリを極力無駄にしない努力を
時には天秤にかけ
どちらを優先するか判断してみてください。
    • good
    • 0
この回答へのお礼

丁寧なご回答ありがとうございます。
メモリのnewとdeleteを繰り返すと、フラグメントが発生するのですか。。それは初めて聞きました、参考にさせて頂きます。
ということは、その都度のメモリの使用のみを考えて、あるクラスの各関数内で、ローカル変数として、別のクラスのオブジェクトのnew.deleteを繰り返してメモリを確保するよりも、長期的にみてあるクラスのグローバル変数として他のクラスのオブジェクトを宣言し、コンストラクタでnew,デストラクタでdelteした方がよいとも考えられるということですね。

また、教えて頂いたクラスのオブジェクトの前者、後者の違いですが、あるクラスで別のクラスのオブジェクトを宣言するときは、ポインタとして呼び出す方が、利便性があるということですね。

ご回答ありがとうございます。

お礼日時:2009/05/27 09:00

その都度、オブジェクトを生成して済むのであれば、静的メンバ関数にできないか検討してみてはどうでしょうか?


静的メンバ関数にできるのであれば、オブジェクトを生成する必要がなくなりますから、メモリの使用量はゼロになります。
    • good
    • 0
この回答へのお礼

その都度クラス1,クラス3で呼ばれるクラス2の関数を静的関数にしてみたらいい、ということでしょうか?
そうすれば、確かにメモリの使用はなくなりますよね。
その方法で考えてみます!!

お礼日時:2009/05/25 18:26

クラスのインスタンスがメモリー上に実在するのは


クラスのコンストラクタが実行されてインスタンス
が生成されてから、そのインスタンスがデストラクタで
破棄されるまでで、これをクラスの寿命といいます。
つまり生きているクラスは全てメモリ上に存在するわけです。

以上の理屈より、ご質問の件は自明ですね(^^)/。
    • good
    • 0
この回答へのお礼

ということはクラス1のメンバ変数にクラス2のインスタンスを指定し、クラス1のコンストラクタでnewでメモリを確保すると、クラス1のデストラクタが呼ばれるまで常にクラス2のインスタンス分のメモリが確保され続けてしまうということですね?
逆に、その都度new,deleteを呼ぶことでインスタンス分のメモリの確保・開放を繰り返しているということですか。

だとしたら、面倒でも何度も繰り返しインスタンスを作成したほうがメモリの面ではいいということですね。

お礼日時:2009/05/25 18:23

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!