C++

オブジェクトの配列を宣言する方法は整数型や少数型の配列を宣言する方法と全く同じです。


違う点を1つだけ挙げるとすれば、オブジェクトの配列を初期化するには、クラスにコンストラクタを用意する必要がある点です。
BlackBoxクラスのコンストラクタを改造して、引数を受け取る形にしましょう。


7

ただし、この構文はコンストラクタが引数を1つしか受け取らない場合にのみ使用可能です。また、配列の初期化では初期化子を指定しなければデフォルトでは0で初期化されましたが、オブジェクト配列においてその機能はありません。更に、初期化子を省略することもできません。

コンストラクタにて引数を2つ以上受け取る場合、{};内には初期化子ではなく、コンストラクタを宣言する必要があります。


6

このエントリーをはてなブックマークに追加

改めて紹介する内容ではないかもしれませんが、オブジェクトへのポインタ変数を作成することができます。それは、今までに作成してきた整数型へのポインタ変数などと同じように。

ポインタを介した操作は既にたくさんやってきました。
しかし、オブジェクトへのポインタ変数そのものを宣言する方法は紹介していませんでした。

前回作成したBlackBoxクラスを簡略化し、オブジェクトへのポインタ変数を宣言してみましょう。


5


ご覧のように整数型へのポインタ変数を宣言する時と全く同じです。
このエントリーをはてなブックマークに追加

const修飾子とは、指定した変数が参照専用であることを意味します。
つまり、constを指定した値を変更することはできません。
2


クラス内のメンバ変数を初期化する場合、=でCライクな初期化をするのではなくコンストラクタ関数内で代入して下さい。


なぜクラス内でCライクな初期化ができないかというと、クラスはあくまで抽象的な存在であり、実体を生成するのは宣言するタイミングです。そのタイミングでコンストラクタが呼び出されるので、そこで初めてメモリ領域へ書き込めるようになるわけです。
このエントリーをはてなブックマークに追加

C++でコメントを書く際は、//を2つ並べます。
Cでコメントを書く際は、/* でコメントを始め、*/までをコメントとしていましたが、そちらも使用可能です。

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
これまでストリームやマニピュレータを使用する時は、std::cout あるいは std::endlなどと書いてきました。ところでこのstd::はなんなのでしょうか。

std::は名前空間です。名前空間とはある変数や関数を一つのグループとして扱う機能のことです。
標準入出力ストリームや標準入出力マニピュレータはstd名前空間内に存在する為、std::を付けていたのです。しかし、毎回std::を付けるのは辛いので、std::は省略できます。

ソースファイルのいずれかの場所にusing namespace std;と書いて下さい。直訳で名前空間stdを使用しますですね。

この行がコンパイラに読まれると、同一ソースファイルのそれ以降の行はstd::を付けなくてもストリームやマニピュレータを検出できるようになります。内部的には、識別されない関数を見つけると、std::で補完するといった形です。

問5:using namespace std;を使用して、画面にhelloと出力するプログラムを書きなさい。

名前空間はプログラマが定義することもできますが、作成する機会は少ないのでここでは割愛します。名前空間はクラスよりさらに大きい概念と考えればよいでしょう。
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
これまでクラスにはpublic:を指定してきました。しかしここにはprivate:を指定することもできます。

private:を指定すると、その行以下のメンバには、そのクラスのメンバしかアクセスできなくなります。このようなメンバ(クラスに所属する変数や関数)を非公開メンバと言います。
つまりこのままではSecretNumberの値は他のクラスやmain関数から知ることはできません。

ところでアクセス指定子(public:など)は、書いた行以下に範囲が及ぶことを覚えているでしょうか?
つまり、private:の下から更にpublic:と書けば、public:以下の行は公開メンバになるということです。


このように、同じクラスでも公開領域と非公開領域を分けることができるのです。
非公開領域には、ほかのクラスやmain関数から変更されて欲しくない変数を記述するのが主流です。
例えば、ユーザーIDを保持する変数がmain関数から呼び出せるとどうでしょうか?
うっかりプログラマがユーザーIDを変更する関数を書いてしまう(あるいはバグによりそうなってしまう)可能性もあります。このようなヒューマンエラーを回避する為に領域を分ける機能が用意されているのです。

では、private:メンバを参考にしたい時はどうすればよいのでしょうか。
多くのプログラマは、get系の関数をpublic:にて実装してmain関数からはその関数を呼び出します。

private:メンバは、同じクラスからしかアクセスできないのでした。
その為このような関数を作成し、main関数側でSecretNumberの情報が必要な時は、GetSecretNumberを発動します。仮に取得したSecretNumberの値を書き換える処理がmain関数で行われるとしても、GetSecretNumberから返却された値は、本物のSecretNumberのコピーでしかない為、SecretNumberの値が書き換えられることはありません。GetSecretNumberで取得した値は、そのまま捨てても構いません。

では、main関数からGetSecretNumberを使用してSecretNumberを参考してみましょう。

1


最も、今回はSecretNumberを初期化していない為、値は不定なのですが。(環境により不定の値は変わります)
このエントリーをはてなブックマークに追加

前回のポインタ渡しはCの機能でした。そしてポインタ渡しは全く以って正しい手法で、C++でも使用可能です。
しかし、C++には更に安全な参照があります。
参照は、ポインタの構文をより直感的に、かつ安全にしたものと言えます。

参照渡しとは、オブジェクトのアドレスを関数へ渡す手法です。
……ここまではポインタと同じなのですが、構文が違います。
ポインタ渡しでは、オブジェクトのアドレスを受け取る関数の仮引数には型名*を指定しました。
参照渡しでは、オブジェクトのアドレスを受け取る関数の仮引数には型名&を指定します。

EnemyCharacter型のオブジェクトのアドレスを受け取るPowerUP2関数を書きましょう。


参照では、.演算子を使用します。
この構文が非常に重要で、参照では->や*を使用する必要が一切ありません。

参照渡しを行うには、オブジェクトのアドレスを受け取る関数の仮引数に&を指定すればよいだけです。それだけで、値渡しと全く同じように操作を行うことができます。

main関数からPowerUP2関数を呼び出してみます。


main関数側からも、Enemy1オブジェクトを渡す際に、なんらかの演算子を付けていません。
ポインタと違い、&演算子を付ける必要がないのです。
なぜなら、関数側に&が付いている時点でアドレスを関数へ渡すことが明白だからです。
よって、オブジェクト名を指定するだけで、そのオブジェクトのアドレスがコンパイラによって関数へ渡されます。

参照渡しの優れた点は、構文が値渡しとほとんど同じである点です。
違うのは、仮引数を指定するところだけで、C++では仮引数へ&を付けるか否かで値渡しか参照渡しかが決定されます。

main関数からのオブジェクトの渡し方が値渡しと同じな為、関数名を変える必要があります。main関数の処理から見れば、値渡しも参照渡しも同じ構文だからです。

オブジェクトを関数へ渡す時は、是非参照渡しを使用して下さい。煩わしいデストラクタのことを考える必要がなくなるばかりか、値渡しとほとんど同様の構文を使用することで、*を付けるか否かや、->か.かを考える必要がなくなります。
このエントリーをはてなブックマークに追加

↑このページのトップヘ