1-1 C++の基礎

このサイトでは基本的にCではなくC++を使用します。
C言語とはいわゆるプログラム言語です。
というかこれを知らなければ話にならないので、資料や本などで勉強しましょう!

このサイトではCのことについて書いてるわけではなく、
Cを使って音ゲーを作ることを目的にしてるのでこの辺は説明していません。

Cなんて知らないよと言う人は、まずはCの基礎から勉強してください。



■C++

「しーぷら」または「しーぷらぷら」。いろんな読み方があります。

どちらかというと、このマニュアル(DirectXもそうだが)はC++言語を使うのが暗黙の了解になってます。
とりあえずCを触ったことがある方には簡単に説明します。

Cでは構造体というものがあって、たくさんの変数などを1つのまとまった変数内に入れてしまい、
これを使って管理するというものがありますね。
でもこの中には変数(intとかcharとか)しか入れられませんでしたね。
しか~し!C++ではこの中に関数も入れてしまうことが出来るんです~。
通常はこれをクラスと言ってますが、実は構造体とクラスはほとんど同じなんですよね。

簡単に書くと、Cでは・・・

struct KOUZOUTAI {
    int     x;
    char    dat[100];
};

これをクラスで定義すれば・・・

class KOUZOUTAI {
public:
    int     x;
    char    dat[100];
};

という感じになります。
ところで、みょ~に見慣れない単語がありますね。
public: とはなんぞや?と思うでしょうが、
実はこれがC++で追加されたキーワードなんです。
public: とはこれ以降の定義された変数や関数は、
そとのプログラムから読み出すことが出来ることを意味します。
間違えて
public: を付け忘れるとプログラムからこれらを参照できなくなって、
コンパイルエラーになってしまいます。

上の方で構造体とクラスはほとんど同じと言ったのは、
structでは、最初に何もキーワード定義しない場合は暗黙的に public: というのになっていて、
classでは、最初はprivate: という参照不可の状態になっているという違いだけなんです。
なお、きちんと
struct内にもこれらのキーワードは使えます。

そして、みんな
classを使うのは単にstructより見た目がカッコイイからというだけのことなんですね!(爆)

ではここで、実用的な定義方法を・・・

class KOUZOUTAI {
public:
    int     x;
private:
    char    dat[100];
protected:
    int     xx;
};

キーワードは3つしかありません。
public:private:protected: ですが、この例では private:protected:は同じ意味になります。
この2つが意味を成すのは、最初に作ったクラスを、新しいクラスに継承させる場合だけですが、
ここではそんなむずかし~ことを書いても意味が無いので、これは自分で勉強してくださいって感じです。


■同名の関数

C++では引数が違う場合、同名の関数を定義することが出来ます。

たとえば以下のような感じです。

int GetParam( void );
int GetParam( LPBYTE dat );

void Test()
{
      :
    int a = GetParam();
    int b = GetParam( &binary );
      :
}

コンパイラが引数を見て自動的にリンク先を変えてくれるため、このような書き方が出来ます。

なお、戻り値が違う場合は違う関数とはみなされませんので、
もし戻り値が変わるような関数の場合は、今までどおり関数名を別名にする必要があります。



■引数のデフォルト値

C++では、関数などの引数にデフォルト値をセット出来るようになり、
プログラムを打つ際に全ての引数を書く必要がなくなりました。

これは関数のプロトタイプで指定しますが、引数が複数ある場合でデフォルト値を付けた引数以降の引数は、
すべてデフォルト値を入れる必要が発生します。
具体的には以下のようなプロトタイプとなります。

BOOL GetParam( int type,LPBYTE src=NULL,int size=-1 );  ←これはOK
BOOL GetParam( int type,LPBYTE src=NULL,int size );     ←これはNG

下の関数の定義は、srcでNULLを指定したのに、そのあとのsizeにデフォルト値が無いため、
コンパイルエラーが発生します。

実際にこの関数をデフォルト値を利用して呼び出すと以下のようになります。

GetParam( 0 );
GetParam( 0,(LPBYTE)&buf );
GetParam( 0,(LPBYTE)&buf,128 );

デフォルト値を利用するところから括弧で閉じることで、それ以降の引数を省略することが出来ます。
また、場合によっては途中の引数は省略せずに指定することも出来るため、
その関数内でデフォルトだったらこうするというような処理をいろいろ作ることが出来たり、
プロトタイプのデフォルト値を変更するだけで、この関数をデフォルトで呼び出している部分を
ごっそりその値に入れ替えることが出来るため、効率がよくなったりします。



■クラス関数

やってきました。これをなかなか理解出来ない人がた~くさんいるみたいですが、
音ゲー作るのには結構重要なので、説明したいと思います。

上の方で構造体の中に関数を入れられると言いましたが、
そんなことをすると、配列として使えないんじゃないかと疑問に思うかもしれません。
自分も最初そうでしたが、この使い方は、クラスを構造体としてではなく、
1つのライブラリ関数として使う作り方である、
ということにすれば納得が出来ます。

さて、例を見てみましょう。

// クラス定義(.hファイル)
class CTest {
protected:
    int a;
public:
    void SetA( int _a );
    int GetA( void );
};


// 関数の実体(.cppファイル)
void CTest::SetA( int _a )
{
    a = _a;
}

int CTest::GetA( void )
{
    return a;
}

さっぱりですか?
よ~く見てみると、クラス定義内には参照できない int a があります。
そして、
publicより下には、見慣れた関数のプロトタイプがあります。
publicなのでこれらの関数はプログラムから実行出来ますね。
でも、実際の 変数a というのは外には出ていないので、これに直接アクセスすることは出来ません。
その代わりに関数を使ってアクセスをしています。

関数の実体には、さらに見慣れない「::」のマークが。
これはクラス定義された場合の、関数の実体を定義する場合に識別するような物なので、
必ずつけなければなりません。

では、この関数の簡単な動作の説明です。
まず 変数a というのはクラスの内部で保持している変数です。
これに SetA()という関数を使って値を入れることが出来ます。
逆にGetA()という関数を使うと、入れた値を取得することが出来ます。

逆にクラス内部から見ると、
SetA()関数で渡された _a という値を、
protectedされた変数a に入れます。
SetA()GetA()という関数はクラス内の関数なので、
変数a には、自由に値の代入や参照などが出来ます。

なんでこんな面倒なことをするのかというと、
この例ではまだ規模が小さいので、グローバルにint aとすればいいですが、
大きなプログラムになると、たくさんの変数や関数が入り混じり、
そのせいで誤って同一の変数を使ってしまい、見えないバグを出してしまう恐れがあるからなんです。

利点としては、誰かが作ったクラスを使うときに、
ヘッダに定義されている関数(この場合SetA()やGetA())の内容さえ知っていれば、
その中の関数が何をしてようが、自分は一切関係なくただそれを実行すればいいだけなので、
安全で簡単にプログラムが作ることが出来るのです。

ちなみに、SetA()やGetA()などクラス内の関数を別名「メソッド」と呼びます。
また、int aなどの変数は「プロパティ」と呼びます。
これはかなり重要な要素なので覚えておきましょう。
このサイトではこちらの呼び方を使うところもあります。

また、メソッドの定義時には普通の関数同様に、引数にデフォルト値を付けた状態で定義できます。
特にこのサイト内のライブラリは、ほとんどのものでデフォルト値を設定しています。