C++スコーラ
アクセス制御
最終更新:
cschola
-
view
アクセス制御
アクセス修飾子
オブジェクトのメンバはアクセス制限をする事ができます。
public | どこからでもアクセス可能 |
private | そのクラス内からのみアクセス可能 |
protected | そのクラスとその派生クラスからアクセス可能(後の章で説明) |
メンバ変数をprivateにすると外部からの直接的な参照と変更ができなくなります。
これにより変更されたくない変数を隠したり、値を安全に処理させることが可能です。
これにより変更されたくない変数を隠したり、値を安全に処理させることが可能です。
- 値の代入に関数を使い、不正な値が代入されないようにチェックする。
- 値の変更に伴い、関連する処理を実行させる。
- メンバ変数を隠し、クラスの内部処理専用変数として使う。
アクセス制限の例
/*--------------Character.hの中身----------------*/ #pragma once #include < iostream > #include < string > // キャラクタークラス class Character{ private: //【メンバ変数】 std::string name; // 名前 int HP; // 体力 int STR; // 攻撃力 public: //【メンバ関数】 Character(std::string name, int HP, int STR); // コンストラクタ ~Character(); // デストラクタ void Damage(int damage); // ダメージ関数 };
/*--------------Character.cppの中身----------------*/ #include "Character.h" using namespace std; // コンストラクタ Character::Character(string name, int HP, int STR){ this->name = name; this->HP = HP; this->STR = STR; } // デストラクタ Character::~Character(){ // 何もしない } // ダメージ関数 void Character::Damage(int damage){ this->HP -= damage; cout << name << "は" << damage << "のダメージをうけた" << endl; }
基本的には、変数はprivate 関数はpublicに指定します。
メンバ変数の読み書き
不正アクセス対策上の理由で、メンバ変数は基本的にprivateであるべきです。
しかし、privateなメンバには外部から参照できません。
しかし、privateなメンバには外部から参照できません。
/*--------------main.cppの中身----------------*/ #include "Character.h" int main(){ using namespace std; // Characterクラスの実体「hero」を作成 Character* hero = new Character("勇者", 10, 2); // 勇者のSTRを255に変更 hero->STR = 255; //【エラー:hero->STRを参照できない】 hero->Damage(5); // 唐沢に5ダメージ // 勇者のHPを表示 cout << "HP:" << hero->HP << endl; //【エラー:hero->HPを参照できない】 delete hero; //「hero」を削除 return 0; }
しかし、メンバを参照したい場合はあります。その場合はアクセス用の関数を使います。
アクセス用の関数 ゲッターとセッター
メンバ変数の参照用関数をゲッター、代入用関数をセッターと言います。
/*--------------Character.hの中身----------------*/ #pragma once #include < iostream > #include < string > // キャラクタークラス class Character{ private: //【メンバ変数】 std::string name; // 名前 int HP; // 体力 int STR; // 攻撃力 public: //【メンバ関数】 Character(std::string name, int HP, int STR); // コンストラクタ ~Character(); // デストラクタ void Damage(int damage); // ダメージ関数 //【ゲッター】 int GetHP(); // HP //【セッター】 void SetSTR(int STR); // STR };
/*--------------Character.cppの中身----------------*/ #include "Character.h" using namespace std; // コンストラクタ Character::Character(string name, int HP, int STR){ this->name = name; this->HP = HP; this->STR = STR; } // デストラクタ Character::~Character(){ // 何もしない } // ダメージ関数 void Character::Damage(int damage){ this->HP -= damage; cout << name << "は" << damage << "のダメージをうけた" << endl; } //【ゲッター】 int Character::GetHP(){ return this->HP; } //【セッター】 void Character::SetSTR(int STR){ this->STR = STR; }
/*--------------main.cppの中身----------------*/ #include "Character.h" int main(){ using namespace std; // Characterクラスの実体「hero」を作成 Character* hero = new Character("勇者", 10, 2); // 勇者のSTRを255に変更 hero->SetSTR(255); // STRのセッター SetSTR を呼ぶ hero->Damage(5); // 勇者に5ダメージ // 勇者のHPを表示 cout << "HP:" << hero->GetHP() << endl; // HPのゲッター GetHP を呼ぶ delete hero; //「hero」を削除 return 0; }
セッターとゲッターを使ってprivate変数にアクセスしています。
回りくどく感じると思いますが、どうしてもprivate変数にアクセスしたい場合はこれを使いましょう。
回りくどく感じると思いますが、どうしてもprivate変数にアクセスしたい場合はこれを使いましょう。
セッターゲッターの罠
ゲッターは変数の内容を参照するだけなので多少あっても問題はないですが、
セッターは内容を書き換えることができてしまうので極力避けるべきです。
セッターは内容を書き換えることができてしまうので極力避けるべきです。
また、一つの変数にセッターゲッターを両方用意するのは絶対に避けてください。
セッターゲッター両方用意すると実質publicになってしまいます。
セッターゲッター両方用意すると実質publicになってしまいます。
セッターやゲッター内で特別な処理をしている場合はこれに限りません