
C++入門|カプセル化とアクセス関数
戦士の本当の力は、外から直接いじらせない。privateで守り、setとgetで安全に扱うのが、C++のカプセル化の基本です。
C++のクラスでは、メンバ変数とメンバ関数を1つのまとまりとして扱います。
ここまでの学習では、メンバ変数をpublicにして、main.cppから直接値を代入する書き方を使ってきました。
たとえば、戦士の戦闘力を表すメンバ変数がpublicであれば、次のように外から直接変更できます。
warrior.power = 500;これは分かりやすい書き方ですが、実際のプログラムでは少し注意が必要です。
なぜなら、publicなメンバ変数は、クラスの外側から自由に変更できてしまうからです。
もし戦闘力にマイナスの値や、想定外の値を入れられると、プログラムの動きがおかしくなる可能性があります。
そこで使うのが、カプセル化です。
カプセル化とは、クラスの内部データをprivateで守り、必要な操作だけをpublicなメンバ関数として公開する考え方です。
ドラゴンボール風にたとえるなら、戦士の本当の戦闘力や潜在能力を、外部の司令室から直接書き換えられないように、修行カプセルの中に守っておくようなものです。
外からは、直接データに触るのではなく、決められた入口を通して操作します。
その入口になるのが、アクセス関数です。
| 用語 | 意味 | ドラゴンボール風のイメージ |
|---|---|---|
| privateメンバ変数 | クラス外から直接触れないデータ | 戦士の内側に隠された戦闘力 |
| publicメンバ関数 | クラス外から呼び出せる操作 | 修行カプセルの操作パネル |
| セッター | privateな値を設定する関数 | 戦闘力を安全に登録する入口 |
| ゲッター | privateな値を取得する関数 | 戦闘力を読み取るスカウター |
| カプセル化 | 内部データを守り、必要な操作だけ公開する考え方 | 秘密の力をカプセル内に守る仕組み |
今回の記事では、privateなメンバ変数を直接触らず、setPowerとgetPowerというアクセス関数を使って値を設定・取得する方法を学びます。
図:カプセル化はprivateな力を守る修行カプセル

この図が示していること
この図では、privateなメンバ変数m_powerを直接外から触らせず、publicなsetPowerとgetPowerを通して扱う様子を表しています。
main.cppのようなクラス外からは、m_powerへ直接アクセスできません。
代わりに、setPowerで値を設定し、getPowerで値を取得します。
これが、カプセル化とアクセス関数の基本的な考え方です。
カプセル化とは何か
カプセル化とは、クラスの中にあるデータを外から直接触れないようにし、必要な操作だけを外に公開する考え方です。
C++では、privateを使うことで、メンバ変数をクラスの外から直接アクセスできないようにできます。
private:
int m_power;このように書くと、m_powerはクラスの外側から直接使えません。
たとえば、main.cppから次のように書くことはできません。
warrior.m_power = 500;m_powerがprivateだからです。
ただし、同じクラスのメンバ関数の中からはm_powerを使えます。
そのため、値を設定する関数や、値を取得する関数をpublicに用意します。
public:
void setPower(int power);
int getPower();このようにして、privateなメンバ変数へアクセスするための入口を作ります。
なぜカプセル化が必要なのか
カプセル化が必要な理由は、大きく分けて2つあります。
1つ目は、意図しない値の変更を防ぐためです。
もし戦闘力を表す変数がpublicであれば、main.cppからどこでも自由に値を変更できます。
warrior.power = -9999;このような値が入ってしまうと、戦闘力として不自然です。
プログラムの計算結果もおかしくなる可能性があります。
privateにしておけば、外から直接書き換えられません。
そして、setPowerの中で必要に応じて値のチェックを行うこともできます。
2つ目は、処理をクラスの中にまとめられるためです。
戦闘力を設定するときのルールや、値を取得するときの処理を、あちこちに書くのではなく、KiWarriorクラスの中にまとめられます。
これにより、あとからプログラムを見た人も理解しやすくなります。
また、変更が必要になったときも、クラスの中の処理を直せばよいので、影響を小さくしやすくなります。
ドラゴンボール風に言えば、戦士の潜在能力を外部から勝手に変更させるのではなく、修行カプセルの操作パネルを通して安全に設定するイメージです。
アクセス関数とは何か
アクセス関数とは、privateなメンバ変数へ値を設定したり、値を取得したりするためのメンバ関数です。
代表的なものが、セッターとゲッターです。
| 種類 | 役割 | 例 |
|---|---|---|
| セッター | privateなメンバ変数に値を設定する | setPower(int power) |
| ゲッター | privateなメンバ変数の値を取得する | getPower() |
セッターは、setから始まる名前にすることが多いです。
ゲッターは、getから始まる名前にすることが多いです。
たとえば、m_powerというメンバ変数なら、次のような名前にします。
| メンバ変数 | セッター | ゲッター |
|---|---|---|
| m_power | setPower | getPower |
このように名前をそろえると、どのメンバ変数を扱う関数なのかが分かりやすくなります。
カプセル化のサンプルプログラム
ここからは、カプセル化とアクセス関数を使ったサンプルプログラムを見ていきます。
今回作成するのは、KiWarriorクラスです。
KiWarriorクラスでは、戦士の戦闘力を表すm_powerをprivateにします。
そして、m_powerに値を設定するsetPower、m_powerの値を取得するgetPowerをpublicにします。
ファイル構成は次の3つです。
| ファイル | 役割 |
|---|---|
| ki_warrior.h | KiWarriorクラスの宣言を書く |
| ki_warrior.cpp | setPowerとgetPowerの中身を書く |
| main.cpp | KiWarriorインスタンスを使う |
KiWarriorクラスの宣言
プロジェクト/ファイル名: Chap3_04/ki_warrior.h
#ifndef _KI_WARRIOR_H_
#define _KI_WARRIOR_H_
class KiWarrior {
public:
// 戦闘力を設定するセッター
void setPower(int power);
// 戦闘力を取得するゲッター
int getPower();
private:
// 外から直接変更できない戦闘力
int m_power;
};
#endif // _KI_WARRIOR_H_このヘッダーファイルでは、KiWarriorクラスを宣言しています。
ポイントは、m_powerがprivateに置かれていることです。
private:
int m_power;m_powerは、戦士の戦闘力を表すメンバ変数です。
privateなので、main.cppから直接アクセスできません。
その代わりに、publicなメンバ関数としてsetPowerとgetPowerを用意しています。
public:
void setPower(int power);
int getPower();この2つがアクセス関数です。
| メンバ | アクセス指定子 | 役割 |
|---|---|---|
| setPower | public | m_powerに値を設定する |
| getPower | public | m_powerの値を取得する |
| m_power | private | 戦闘力を保存する |
main.cppからは、m_powerを直接触るのではなく、setPowerとgetPowerを使います。
図:セッターとゲッターでprivateな戦闘力を扱う

この図が示していること
この図では、privateなm_powerを、setPowerとgetPowerを通して扱う流れを表しています。
main.cppからm_powerへ直接アクセスすることはできません。
しかし、publicなsetPowerを呼び出せば値を設定できます。
また、publicなgetPowerを呼び出せば値を取得できます。
これにより、戦闘力という内部データを守りながら、必要な操作だけを外に公開できます。
setPowerとgetPowerの定義
次に、ki_warrior.cppでメンバ関数の中身を書きます。
プロジェクト/ファイル名: Chap3_04/ki_warrior.cpp
#include "ki_warrior.h"
// 戦闘力を設定する
void KiWarrior::setPower(int power) {
m_power = power;
}
// 戦闘力を取得する
int KiWarrior::getPower() {
return m_power;
}ここでは、setPowerとgetPowerを定義しています。
setPowerは、引数powerで受け取った値を、privateなメンバ変数m_powerへ代入します。
void KiWarrior::setPower(int power) {
m_power = power;
}getPowerは、m_powerの値をreturnで返します。
int KiWarrior::getPower() {
return m_power;
}セッターの役割
セッターは、privateなメンバ変数に値を設定するための関数です。
今回のセッターはsetPowerです。
void KiWarrior::setPower(int power) {
m_power = power;
}引数powerには、外から設定したい戦闘力が渡されます。
その値を、クラス内部のm_powerに代入しています。
| 名前 | 役割 |
|---|---|
| power | setPowerに渡される引数 |
| m_power | KiWarriorクラスが持つprivateなメンバ変数 |
ドラゴンボール風に言えば、setPowerは修行カプセルの登録ボタンです。
外から戦闘力を直接書き換えるのではなく、登録ボタンを通して戦闘力を設定します。
ゲッターの役割
ゲッターは、privateなメンバ変数の値を取得するための関数です。
今回のゲッターはgetPowerです。
int KiWarrior::getPower() {
return m_power;
}getPowerは、m_powerの値をreturnで返します。
main.cppからgetPowerを呼び出すと、m_powerの値を受け取れます。
ドラゴンボール風に言えば、getPowerはスカウターです。
戦士の内部にある戦闘力を、外から安全に読み取るための窓口になります。
main.cppからアクセス関数を使う
最後に、main.cppでKiWarriorクラスを使います。
プロジェクト/ファイル名: Chap3_04/main.cpp
#include <iostream>
#include "ki_warrior.h"
using namespace std;
int main(int argc, char** argv) {
// KiWarriorクラスのインスタンスを生成する
KiWarrior warrior;
// セッターを使って戦闘力を設定する
warrior.setPower(500);
// ゲッターを使って戦闘力を取得して表示する
cout << warrior.getPower() << endl;
// プログラムが正常に終わったことを示す
return 0;
}実行結果は次のようになります。
500このプログラムでは、KiWarriorクラスからwarriorというインスタンスを作っています。
KiWarrior warrior;次に、setPowerを使って戦闘力を設定しています。
warrior.setPower(500);そして、getPowerを使って戦闘力を取得し、coutで表示しています。
cout << warrior.getPower() << endl;ここで大切なのは、main.cppからm_powerへ直接アクセスしていないことです。
privateなメンバ変数には直接アクセスできない
m_powerはprivateなので、main.cppから次のようには書けません。
warrior.m_power = 500;このように書くと、ビルドエラーになります。
なぜなら、m_powerはKiWarriorクラスの内部でだけ扱えるメンバ変数だからです。
正しくは、setPowerを通して値を設定します。
warrior.setPower(500);値を取得するときも、m_powerを直接読むのではなく、getPowerを使います。
warrior.getPower()| やりたいこと | 直接アクセス | アクセス関数を使う |
|---|---|---|
| 戦闘力を設定する | warrior.m_power = 500; は不可 | warrior.setPower(500); |
| 戦闘力を取得する | warrior.m_power は不可 | warrior.getPower(); |
このように、privateなメンバ変数は外から直接触れないようにし、publicなアクセス関数を通して扱います。
カプセル化された処理の流れ
このプログラムの処理を順番に追うと、次のようになります。
| 手順 | 処理 | 内容 |
|---|---|---|
| 1 | KiWarrior warrior; | インスタンスを生成する |
| 2 | warrior.setPower(500); | セッターで戦闘力を設定する |
| 3 | m_power = power; | クラス内部でm_powerに値が入る |
| 4 | warrior.getPower(); | ゲッターで戦闘力を取得する |
| 5 | return m_power; | クラス内部の値を返す |
| 6 | coutで表示 | 500が表示される |
main.cppから見えるのは、setPowerとgetPowerだけです。
m_powerの存在は、クラス内部に隠されています。
このように、内部のデータをprivateで守り、必要な入口だけをpublicで公開するのがカプセル化です。
図:main.cppから見えるのはsetPowerとgetPowerだけ

この図が示していること
この図では、main.cppからKiWarriorオブジェクトを使う流れを表しています。
main.cppから見えるのは、publicなsetPowerとgetPowerです。
privateなm_powerはカプセル内部に守られていて、外から直接触ることはできません。
setPowerを通してm_powerに値を設定し、getPowerを通してm_powerの値を取得します。
セッターだけ、ゲッターだけにすることもできる
アクセス関数は、必ずセッターとゲッターを両方用意しなければならないわけではありません。
たとえば、ゲッターだけを用意すれば、外から値を読むことはできるが、変更はできないメンバ変数になります。
| 用意する関数 | 外からできること | イメージ |
|---|---|---|
| セッターとゲッター | 設定も取得もできる | 読み書き可能 |
| ゲッターだけ | 取得だけできる | 読み取り専用 |
| セッターだけ | 設定だけできる | 書き込み専用 |
たとえば、戦士のIDのように、外から読み取りはできても変更させたくないものは、ゲッターだけにすることがあります。
一方で、内部処理にだけ使う値であれば、アクセス関数をまったく用意しないこともあります。
このように、アクセス関数をどう用意するかによって、外からできる操作を細かく制御できます。
m_を付けるメンバ変数名
今回のサンプルでは、メンバ変数名をm_powerにしています。
int m_power;このm_は、この変数がメンバ変数であることを分かりやすくするための接頭辞です。
たとえば、setPowerでは、引数powerとメンバ変数m_powerが登場します。
void KiWarrior::setPower(int power) {
m_power = power;
}このとき、m_powerはメンバ変数、powerは引数だと見分けやすくなります。
| 名前 | 意味 |
|---|---|
| m_power | クラスが持つメンバ変数 |
| power | setPowerに渡される引数 |
m_を付ける書き方は、単純化されたハンガリアン記法のような考え方として紹介されることがあります。
現在のC++では、プロジェクトやチームによって命名規則はさまざまですが、入門段階では、メンバ変数と引数を区別しやすいという利点があります。
セッターとゲッターの名前の付け方
セッターとゲッターの名前は、扱うメンバ変数が分かるように付けると読みやすくなります。
今回のメンバ変数はm_powerです。
そのため、m_を除いたpowerをもとにして、次のように名前を付けています。
| メンバ変数 | セッター | ゲッター |
|---|---|---|
| m_power | setPower | getPower |
このようにすると、setPowerはm_powerに値を設定する関数、getPowerはm_powerの値を取得する関数だとすぐに分かります。
ほかのメンバ変数でも、同じように名前を付けられます。
| メンバ変数 | セッター | ゲッター |
|---|---|---|
| int m_score | void setScore(int score) | int getScore() |
| double m_value | void setValue(double value) | double getValue() |
| bool m_flag | void setFlag(bool flag) | bool getFlag() |
| string m_name | void setName(string name) | string getName() |
名前を見ただけで、どのメンバ変数を扱う関数なのか分かるようにしておくと、プログラムが読みやすくなります。
カプセル化でプログラムが整理しやすくなる
カプセル化を使うと、クラスの外側と内側の役割を分けられます。
main.cppのようなクラスの外側では、setPowerやgetPowerを呼び出すだけです。
m_powerがどのように保存されているか、内部でどんな処理が行われているかを詳しく知る必要はありません。
一方、KiWarriorクラスの中では、m_powerをどのように扱うかをまとめて管理できます。
| 場所 | 役割 |
|---|---|
| main.cpp | publicな操作を呼び出す |
| KiWarriorクラス内部 | privateなデータを管理する |
| setPower | 値を設定する入口 |
| getPower | 値を取得する入口 |
このように役割を分けることで、プログラムの見通しがよくなります。
大きなプログラムでは、クラスごとに役割を分けて開発することが多くなります。
そのとき、内部データをprivateで守り、必要な関数だけをpublicにする設計はとても重要です。
ドラゴンボール風に言えば、戦士の潜在能力そのものはカプセル内に守り、外部の司令室には安全な操作パネルだけを見せるということです。
カプセル化とアクセス関数で押さえたいポイント
カプセル化とアクセス関数では、次のポイントを押さえておきましょう。
| ポイント | 内容 |
|---|---|
| メンバ変数はprivateにする | 外から直接変更されないようにする |
| 値を設定する関数を用意する | セッターを使う |
| 値を取得する関数を用意する | ゲッターを使う |
| 必要な操作だけpublicにする | 外から使える入口を限定する |
| m_でメンバ変数を区別する | 引数やローカル変数と見分けやすくする |
| 名前をそろえる | setPower、getPowerのように分かりやすくする |
C++では、メンバ変数を何でもpublicにして外から自由に触らせるより、privateで守り、必要な操作だけをpublicな関数として用意する設計がよく使われます。
privateは、戦士の内側にある秘密の力を守るための壁です。
セッターは、その力を安全に設定する入口です。
ゲッターは、その力を安全に読み取る入口です。
この3つの関係を理解すると、C++のカプセル化がかなり自然に見えてきます。
