
C++入門|クラス内のメンバ利用
外から使うときは warrior.power、クラスの中では power。メンバの呼び出し方を覚えれば、オブジェクトが自分の力で動き出します。
C++のオブジェクト指向では、クラスからインスタンスを作り、そのインスタンスが持つメンバ変数やメンバ関数を使って処理を行います。
前回は、Warriorクラスを作り、戦闘力を表すpowerと、修行する動作を表すtrainを用意しました。
今回は、その続きとして、メンバをどのように使うのかを詳しく見ていきます。
メンバとは、クラスの中にあるメンバ変数とメンバ関数の総称です。
| 種類 | Warriorクラスでの例 | 意味 |
|---|---|---|
| メンバ変数 | power | 戦士の戦闘力 |
| メンバ関数 | train(double hour) | 指定した時間だけ修行する |
C++では、インスタンスからメンバを使うときに、ドット演算子 . を使います。
たとえば、warriorというインスタンスがある場合、powerに値を入れるには次のように書きます。
warrior.power = 80;また、trainというメンバ関数を呼び出すには、次のように書きます。
warrior.train(1.5);ドラゴンボール風にたとえるなら、warriorは実際に修行場にいる戦士です。
warrior.power = 80; は、その戦士の戦闘力カプセルに80を設定する命令です。
warrior.train(1.5); は、その戦士に1.5時間の修行を指示する命令です。
つまり、ドット演算子は「この戦士の、この能力や動作を使う」という指定をするための記号です。
図:ドット演算子でメンバ変数にアクセスする

この図が示していること
この図では、warriorというインスタンスの中にあるpowerメンバ変数へ、ドット演算子を使ってアクセスする流れを表しています。
warrior.power = 80; と書くことで、warriorオブジェクトが持っているpowerに80を代入できます。
クラスの外側からメンバを使うときは、変数名.メンバ名という形で書くのが基本です。
前回のWarriorクラスを確認する
まず、前回作成したWarriorクラスの構成を確認しましょう。
Warriorクラスは、次の3つのファイルで構成されています。
| ファイル | 役割 |
|---|---|
| warrior.h | Warriorクラスの宣言を書く |
| warrior.cpp | trainメンバ関数の定義を書く |
| main.cpp | インスタンスを生成してメンバを使う |
このうち、今回特に注目するのは、main.cppでのメンバアクセスと、warrior.cppでのメンバ関数内の処理です。
Warriorクラスの宣言
Warriorクラスには、メンバ変数powerと、メンバ関数trainがあります。
プロジェクト/ファイル名: Chap3_01/warrior.h
#ifndef _WARRIOR_H_
#define _WARRIOR_H_
class Warrior {
public:
// 戦闘力
double power;
// 修行する
void train(double hour);
};
#endif // _WARRIOR_H_このクラス宣言を見ると、Warriorクラスの中にpowerとtrainがあることが分かります。
double power;これは、戦士の戦闘力を表すメンバ変数です。
void train(double hour);これは、指定した時間だけ修行するメンバ関数です。
また、これらはpublicの中に書かれています。
public:publicの中にあるメンバは、クラスの外側からもアクセスできます。
そのため、main.cppからwarrior.powerやwarrior.train(1.5)のように使えるわけです。
メンバ変数へのアクセス
main.cppでは、Warriorクラスからwarriorというインスタンスを作ります。
そのあと、warriorのpowerに値を代入します。
プロジェクト/ファイル名: Chap3_01/main.cpp
#include <iostream>
#include "warrior.h"
using namespace std;
int main(int argc, char** argv) {
// インスタンスを生成する
Warrior warrior;
// 戦闘力を設定する
warrior.power = 80;
// 指定した時間だけ修行する
warrior.train(1.5);
// プログラムが正常に終わったことを示す
return 0;
}ここで注目したいのは、次の行です。
warrior.power = 80;これは、warriorというインスタンスの中にあるpowerメンバ変数に80を代入しています。
| 書き方 | 意味 |
|---|---|
| warrior | Warriorクラスから作られたインスタンス |
| power | warriorが持つメンバ変数 |
| warrior.power | warriorのpowerを指定する |
| warrior.power = 80; | warriorの戦闘力を80にする |
ドット演算子 . は、インスタンスの中にあるメンバを指定するために使います。
ドラゴンボール風にいえば、warriorという戦士の戦闘力カプセルに80を入れているようなイメージです。
メンバ関数へのアクセス
次に、メンバ関数を呼び出す部分を見てみましょう。
warrior.train(1.5);これは、warriorというインスタンスのtrainメンバ関数を呼び出しています。
| 書き方 | 意味 |
|---|---|
| warrior | 対象となるインスタンス |
| train | 呼び出すメンバ関数 |
| 1.5 | train関数へ渡す引数 |
| warrior.train(1.5); | warriorに1.5時間修行させる |
この処理により、warrior.cppに定義されているtrain関数が実行されます。
実行すると、次のような結果になります。
戦闘力80の戦士が1.5時間修行
120ポイント成長しました。ここでは、powerが80、hourが1.5なので、80 × 1.5 = 120 となります。
図:ドット演算子でメンバ関数を呼び出す

この図が示していること
この図では、warrior.train(1.5);によって、warriorオブジェクトのtrainメンバ関数が呼び出される流れを表しています。
train関数の中では、warriorが持つpowerと、引数として渡されたhourを使って、成長ポイントを計算します。
クラスの外側からメンバ関数を呼び出すときは、変数名.メンバ関数名という形で書きます。
メンバを呼び出す基本形
メンバ変数でも、メンバ関数でも、クラスの外側からアクセスするときは基本形が同じです。
変数名.メンバ名たとえば、warriorというインスタンスのpowerを使うなら、次のように書きます。
warrior.powerwarriorというインスタンスのtrainを呼び出すなら、次のように書きます。
warrior.train(1.5)| 使いたいもの | 書き方 | 内容 |
|---|---|---|
| メンバ変数 | warrior.power | warriorのpowerを使う |
| メンバ関数 | warrior.train(1.5) | warriorのtrainを呼び出す |
この「変数名.メンバ名」という形は、C++のオブジェクト指向でとてもよく使います。
ドット演算子を見るときは、「このオブジェクトの中にあるものを使っている」と考えると分かりやすいです。
warrior.cppのtrain関数を見てみよう
次に、メンバ関数の中身を見てみましょう。
プロジェクト/ファイル名: Chap3_01/warrior.cpp
#include "warrior.h"
#include <iostream>
using namespace std;
// 修行する
void Warrior::train(double hour) {
cout << "戦闘力" << power << "の戦士が" << hour << "時間修行" << endl;
cout << power * hour << "ポイント成長しました。" << endl;
}ここで注目したいのは、train関数の中でpowerを使っている部分です。
cout << "戦闘力" << power << "の戦士が" << hour << "時間修行" << endl;
cout << power * hour << "ポイント成長しました。" << endl;main.cppでは、powerにアクセスするときにwarrior.powerと書いていました。
warrior.power = 80;しかし、train関数の中では、単にpowerと書いています。
powerこれは、train関数がWarriorクラスのメンバ関数だからです。
同じクラスの中にあるメンバ変数は、メンバ関数の中からそのままの名前で使えます。
クラス外から使う場合とクラス内で使う場合の違い
ここが今回のいちばん大切なポイントです。
クラスの外側からメンバを使う場合は、どのインスタンスのメンバなのかを明示する必要があります。
そのため、main.cppでは次のように書きます。
warrior.power = 80;
warrior.train(1.5);一方、Warriorクラスのメンバ関数の中では、同じクラスのメンバ変数powerをそのまま使えます。
power * hourこの違いを表にすると、次のようになります。
| 場所 | 書き方 | 理由 |
|---|---|---|
| main.cppなどクラスの外側 | warrior.power | どのインスタンスのpowerかを指定する必要がある |
| main.cppなどクラスの外側 | warrior.train(1.5) | どのインスタンスのtrainかを指定する必要がある |
| Warrior::trainの中 | power | 同じクラス内のメンバ変数なのでそのまま使える |
| Warrior::trainの中 | hour | train関数の引数なのでそのまま使える |
ドラゴンボール風にたとえるなら、main.cppは修行場の外から戦士へ命令している立場です。
そのため、「warriorという戦士のpower」「warriorという戦士のtrain」と、対象をはっきり指定する必要があります。
一方、train関数の中は、warrior自身の内部処理です。
自分自身のpowerを使うので、わざわざwarrior.powerとは書かず、powerだけで通じます。
hourはメンバ変数ではなく引数
train関数では、powerとhourが登場します。
void Warrior::train(double hour)ここでhourは、train関数に渡される引数です。
Warriorクラスのメンバ変数ではありません。
| 名前 | 種類 | 内容 |
|---|---|---|
| power | メンバ変数 | Warriorオブジェクトが持つ戦闘力 |
| hour | 引数 | train関数を呼び出すときに渡される修行時間 |
main.cppで次のように呼び出すと、
warrior.train(1.5);1.5がhourに渡されます。
そのため、train関数の中では、hourの値は1.5になります。
cout << "戦闘力" << power << "の戦士が" << hour << "時間修行" << endl;powerはwarriorが持っている戦闘力です。
hourはtrain関数に渡された修行時間です。
この2つを使って、成長ポイントを計算しています。
power * hourwarrior.powerが80で、hourが1.5なら、計算結果は120になります。
メンバ関数の定義で使うWarrior::train
メンバ関数をクラスの外側で定義するときは、関数名の前にクラス名を付けます。
void Warrior::train(double hour)これは、Warriorクラスのtrain関数を定義しているという意味です。
| 書き方 | 意味 |
|---|---|
| train | 関数名 |
| Warrior::train | Warriorクラスに属するtrain関数 |
| :: | 所属を示すスコープ解決演算子 |
もし単にtrainと書くだけでは、どのクラスのtrainなのか分かりません。
Warrior::trainと書くことで、Warriorクラスのメンバ関数であることを明確にしています。
ドラゴンボール風にいうなら、trainという修行メニューが、Warrior設計図に属していることを示す流派札のようなものです。
クラス内ではメンバ変数をそのまま使える
Warrior::trainの中では、powerをそのまま使っています。
cout << "戦闘力" << power << "の戦士が" << hour << "時間修行" << endl;これは、powerがWarriorクラスのメンバ変数だからです。
同じクラス内のメンバ関数から見れば、powerは自分の中にあるデータです。
そのため、ドット演算子を使わず、そのままpowerと書けます。
cout << power * hour << "ポイント成長しました。" << endl;この計算も、同じクラス内のpowerを使っています。
| 場所 | powerの書き方 |
|---|---|
| main.cpp | warrior.power |
| warrior.cppのWarrior::train内 | power |
この違いを意識できると、クラスの外側と内側の見方がかなり分かりやすくなります。
図:クラス内ではメンバ変数をそのまま使える

この図が示していること
この図では、クラスの外側と内側でメンバ変数の書き方が変わることを表しています。
main.cppのようにクラスの外側から使う場合は、warrior.powerのようにインスタンス名を付けます。
一方、Warrior::trainの中では、同じクラス内のメンバ変数なので、powerとそのまま書けます。
また、hourはメンバ変数ではなく、train関数に渡された引数です。
powerとhourを使って、power * hourの計算を行っています。
メンバ利用の流れを順番に確認する
今回のプログラムの流れを、もう一度順番に見てみましょう。
まず、main.cppでWarriorクラスのインスタンスを作ります。
Warrior warrior;これにより、warriorという実際の戦士オブジェクトができます。
次に、warriorのpowerに80を代入します。
warrior.power = 80;この時点で、warriorの戦闘力は80になります。
次に、trainメンバ関数を呼び出します。
warrior.train(1.5);この呼び出しによって、Warrior::train(double hour)が実行されます。
train関数の中では、powerとhourを使います。
power * hourpowerはwarriorが持っているメンバ変数です。
hourはtrain(1.5)で渡された引数です。
そのため、80 × 1.5 = 120となり、120ポイント成長したと表示されます。
| 手順 | 処理 | 内容 |
|---|---|---|
| 1 | Warrior warrior; | インスタンスを生成する |
| 2 | warrior.power = 80; | メンバ変数powerに80を代入する |
| 3 | warrior.train(1.5); | メンバ関数trainを呼び出す |
| 4 | power * hour | 80 × 1.5を計算する |
| 5 | coutで表示 | 修行結果を表示する |
ドット演算子を使う場面
ドット演算子は、インスタンスの中にあるメンバへアクセスするときに使います。
インスタンス名.メンバ名今回のサンプルでは、次の2つが登場しました。
warrior.power
warrior.train(1.5)| 書き方 | 使っているもの | 内容 |
|---|---|---|
| warrior.power | メンバ変数 | warriorの戦闘力 |
| warrior.train(1.5) | メンバ関数 | warriorに1.5時間修行させる |
ドット演算子を見るときは、「どのオブジェクトのメンバを使っているのか」を読むのが大切です。
warrior.powerなら、warriorのpowerです。
別のインスタンスfighterがあれば、fighter.powerはfighterのpowerになります。
つまり、同じpowerという名前でも、どのインスタンスのpowerかによって別のデータになります。
クラス内のメンバ利用で押さえたいポイント
クラス内のメンバ利用では、次のポイントを押さえておきましょう。
| ポイント | 内容 |
|---|---|
| メンバ変数へアクセス | インスタンス名.メンバ変数名 |
| メンバ関数を呼び出す | インスタンス名.メンバ関数名(引数) |
| クラス内でメンバ変数を使う | メンバ変数名だけで使える |
| クラス外でメンバを使う | どのインスタンスのメンバかを指定する |
| メンバ関数の定義 | クラス名::メンバ関数名で書く |
ドラゴンボール風に言えば、main.cppは外から戦士に指示を出す司令室です。
そのため、warrior.powerやwarrior.train(1.5)のように、対象の戦士をはっきり指定します。
一方、Warrior::trainの中は、戦士自身の内部処理です。
自分のpowerを使うので、powerとそのまま書けます。
クラスの外と中を区別して読む
C++のクラスを読むときは、「今どこからメンバを使っているのか」を意識すると分かりやすくなります。
main.cppのようにクラスの外側から使っているなら、インスタンス名.メンバ名になります。
warrior.power = 80;
warrior.train(1.5);warrior.cppのWarrior::trainの中なら、同じクラスのメンバ変数はそのまま使えます。
power * hourこの違いが分かると、クラスを使ったC++プログラムがぐっと読みやすくなります。
オブジェクト指向では、オブジェクトが自分のデータを持ち、自分の動作を実行します。
warriorはpowerを持ち、trainで修行します。
外からはwarrior.powerやwarrior.train(1.5)で操作し、内部ではpowerを使って処理を進めます。
この感覚をつかめると、C++のクラスとオブジェクトの動きがかなり自然に見えてきます。
