それでは、ここからクラスについて説明します。
オブジェクト指向プログラミングの3つの特徴として、
・カプセル化(カプセライゼーション) ・多態性(ポリモーフィズム) ・継承(インヘリタンス) |
があります。
多態性については、言葉としては使っていませんが、これまでの説明の中にも出てきました。
関数のオーバーロードやテンプレートのところで、複数の機能が1つの関数名で扱える事などが例です。
カプセル化や継承はクラスの中で説明します。
まず、クラス自体は構造体の発展形と考えればそう難しい考え方ではありません。
C++では、クラスと構造体はちょっとした違いしか無いのです。
1つプログラムを書きます。
構造体とクラスの宣言と実体(インスタンス)の作成のサンプルです。
<sample program cpp047-01>
#include <iostream> struct Player { int hp; int mp; }; class Enemy { int m_hp; int m_mp; }; int main() { Player player; Enemy enemy; return 0; } |
キーワードが「struct」と「class」という違い以外は何も変わりがありません。
クラスのメンバ変数には「 m_ 」と言う文字を付けています。
ポインタ変数には「 p 」を付けるとか、bool型には「 b 」を付けるなど、プリフィックス(接頭辞)と言います。
個人的には、メンバ変数にプリフィックスを付けていなかったのですが、Visual Studio Community 2015で色々と面倒な警告が出たので付けるようにします。
メンバ変数へアクセスも「.演算子」で行います。
<sample program cpp047-02>
#include <iostream> struct Player { int hp; int mp; }; class Enemy { int m_hp; int m_mp; }; int main() { Player player; Enemy enemy; player.hp = 100; player.mp = 50; enemy.m_hp = 100; enemy.m_mp = 50; return 0; } |
<コンパイル結果>
error C2248: 'Enemy::m_hp': private メンバー (クラス 'Enemy' で宣言されている) にアクセスできません。 note: 'Enemy::m_hp' の宣言を確認してください note: 'Enemy' の宣言を確認してください error C2248: 'Enemy::m_mp': private メンバー (クラス 'Enemy' で宣言されている) にアクセスできません。 note: 'Enemy::m_mp' の宣言を確認してください note: 'Enemy' の宣言を確認してください
メンバ変数にアクセスしようとしたところエラーになりました。
エラーは「enemy」クラスの方で発生しています。
メッセージには「privateメンバー」という言葉が書いてあります。
C++の構造体とクラスには、メンバ変数を書く場所にprivateとpublicという区別があります。
デフォルトで、構造体はpublic、クラスはprivateになっています。
publicとは「公共の」と言う意味があり、どこからでもアクセス可能です。
privateとは「個人的な」と言う意味があり、この構造体やクラスの内部でしかアクセス出来ません。
キーワードを使って、もっとはっきり書き直します。
<sample program cpp047-03>
#include <iostream> struct Player { public: int hp; int mp; }; class Enemy { private: int m_hp; int m_mp; }; int main() { Player player; Enemy enemy; player.hp = 100; player.mp = 50; enemy.m_hp = 100; enemy.m_mp = 50; return 0; } |
省略されていたキーワードを書き加えました。
クラスの方は、privateと言うキーワードが付いていますので、main関数からはアクセス出来ません。
これをpublicに書き換えると、main関数からでもアクセス可能になります。
<sample program cpp047-03>
#include <iostream>
struct Player {
public:
int hp;
int mp;
};
class Enemy {
public:
int m_hp;
int m_mp;
};
int main()
{
Player player;
Enemy enemy;
player.hp = 100;
player.mp = 50;
enemy.m_hp = 100;
enemy.m_mp = 50;
return 0;
}
|
これでエラーは無くなりました。
しかし、クラスのデフォルトがprivateになっている事には意味があります。
それは「情報隠蔽」という考え方にあります。
どこからでもアクセス出来るとバグが混入する機会を増やすことになりますので、privateな場所にメンバ変数を用意して変数を隠しているのです。
でも、privateにしてしまうと、main関数などからアクセス出来ません。
どのように扱えば良いか、次回で説明します。