えと、一回書いたものが、すべて消えてしまったという、驚愕の自体…
とってもやる気が下がってます。
が!
なんとか、気合を振り絞って書いていきましょう!
…
何書いてたっけ…。
思い出しながら、一つ一つ書いていこ…。
遅らせながら、中原です。
今、ブログを新しくリニューアルしようという計画がでています。
まだ、C++解説の材料が少ないために非常に見にくい状態ですが、その際には、見出しをつけたり、各パートごとに区切って、綺麗にまとめていこうかと思っております。
しばしお待ちを!
さて前回は、
プログラムを書く上でのルール(コーディング規約)、メンバ関数、コンストラクタ、デストラクタ、アクセス指定子 について講義を行いました。
どうでしょう?
みなさん理解できたでしょうか?
ほんとに
基本のことなので、是非覚えちゃってください。
今回はC++でのメモリ確保の方法を、コンストラクタ、デストラクタを踏まえて解説していきたいと思います。
前回はかなり長かったですが、今回はそこまで長くならないはず…。
はず…
では、Let's go!
第3回 C++講座 『C++でのメモリ確保』
[1回]
C言語でのメモリ確保は、みなさんは何を使っていましたか?
勿論、確保には、 malloc、 解放には free ですよね。
じつは
C++言語では、これは使用しません。
いや、使えないことはないのですが…、一つ問題がありまして使われないことが多いのです。
では、その理由を例を出して説明していきたいと思います。
class COniichan
{
private:
int m_iId; //ID番号
public:
COniichan( int Id ) : m_iId( Id )
{
printf("< ID = %-2d > コンストラクタを通りました¥n", m_iId);
}
~COniichan()
{
printf("< ID = %-2d > デストラクタを通りました¥n", m_iId);
}
};
例に使うクラスです。
どういうクラスかと言うと、このクラスの実体が作られたときに ID番号とコンストラクタが通ったことを伝え、実体が破棄されたときに、そのID番号とデストラクタが通ったことを通知するクラスです。
今回の講座では、これを使っていきますので、覚えておいてください。
では、実際に使ってみましょう。
main()
{
COniichan* Nakahara = NULL; //クラスのポインタ宣言
Nakahara = ( COniichan* ) malloc( sizeof(COniichan) );
free( Nakahara );
getch();
}
さて、どう表示されるでしょう。
あれ?
表示されませんよね。
前回、実体が作られたときにコンストラタが通ると言っていたのですが、実は
malloc でメモリ確保、free で解放すると、コンストラクタ、デストラクタが通らないのです。
しかも、
引数も与えることが出来ないですよね。
これは困りました。
初期化が出来ない…。(メモリ確保は出来ています。)
実は、C++言語には専用のメモリ確保の方法があるのです。
main()
{
COniichan* Nakahara = NULL; //クラスのポインタ宣言
Nakahara = new COniichan( 0 );
delete Nakahara;
getch();
}
どうでしょう?
これで、しっかりと表示されますよね。
C++言語の
メモリ確保には、new 演算子を使い、 解放には delete 演算子を使います。
ここで、気をつけなければならないのは、
malloc、free は関数、 new、deleteは演算子なことです。
全く違う動きをすることを覚えていてください。
勿論、malloc で確保した後に deleteで解放や、 new で確保して freeで解放なんて、やってはいけません。
全く違うものなのです。
とはいっても、私も確保のされ方などは詳しくないので、詳しく知りたい方は、調べてみるといいかもです。
誰かメモリ関連の記事書いてくれないかなぁ…。
今日覚えることは、これだけです。
楽ですね~。
なんとか、気が萎えずにすみましたよ。
ですが、みなさんは実体がいつ作られて、いつ破棄されるのか、しっかりと理解できていますか?
クラスを使えばコンストラクタ、デストラクタによって、メモリの確保、解放の瞬間が分かりますので、せっかくですからここで理解してしまいましょう。
main()
{
COniichan* Tsuzi;
COniichan Nakahara( 26 );
COniichan* Tawa;
Tawa = new COniichan( 21 );
Tsuzi = new COniichan( 23 );
COniichan* Kamata;
delete Tsuzi;
Kamata = new COniichan( 30 );
delete Tawa;
delete Kamata;
getch();
}
さて、どういった順番で、コンストラクタが呼ばれ、デストラクタが呼ばれるのかが分かりますか?
さすがに解放のし忘れなどの例は出さないでおきますが…。
(プログラマにとって、解放し忘れ(メモリリーク)はタブーです!)
後、言い忘れてましたが、
C++言語では、変数の宣言がプログラムの途中で書くことが出来ます。
実はこれ、とても便利なんですよ。
例えば、for 文で回すための変数 i やら、最初に宣言しておかなければならないですよね。
しかも、どこで使ったのか、それとも使ってないのか、今使っている最中なのか、宣言しているのかどうか、分からなくなってしまうことってありませんか?
そんなあなたに朗報!
for( int i = 0; i < 20 ; i++){
nakahara[ i ] += 10;
}
こういう使い方も出来るのです。
int i は、勿論ローカル変数なので、
スコープ( 中かっこ {} の中) を抜けると 破棄されます。
ですので、この for 文
専用の i として使用できるですね。
他にも、使いたい部分の前で宣言すると、今から使うぞ! ということが分かりやすく、
他人が見たときに理解してもらいやすくなります。
これは我々ゲームプログラマーとして、
とても重要なことです。
話を戻しまして、今回の問題は宿題として置いておきます。
解答は次回の始めに言いますので頑張って解いてみてください。
コピペで動くはず(¥だけは、このブログでは全角でしか表示できないので直してください)ですので、実際に試してみるのもいいと思います。
Include は忘れないでくださいね。
次回は、C++の三本柱の一つである 『継承』 について説明していきたいと思います。
やっと、ここからがC++言語の本領発揮ですね。
これが出来るようになると、今まで自分達が書いてきたプログラムがちょっと変わった感じになると思います。
楽しみにしていてください。
中原でした。
PR
COMMENT