「アクセス制御」(2021/05/20 (木) 12:52:34) の最新版変更点
追加された行は緑色になります。
削除された行は赤色になります。
*アクセス制御
**アクセス修飾子
オブジェクトのメンバはアクセス制限をする事ができます。
|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;
}
基本的には、&bold(){変数はprivate} &bold(){関数はpublic}に指定します。
//**カプセル化
//クラスを利用する側にとって必要のないメンバは隠すべきです。
//これをカプセル化と言います。
//オブジェクト指向の考え方は、オブジェクト同士のメッセージのやりとりである
//というものがあります。
//メンバ変数を直接読み書きすることはこれに反します。
//オブジェクトは外部のメッセージを受けて動作するものです。
//つまりメンバ変数は隠し
//外部からできる動作のみ公開するべきです。
**メンバ変数の読み書き
不正アクセス対策上の理由で、メンバ変数は基本的にprivateであるべきです。
しかし、privateなメンバには外部から参照できません。
/*--------------main.cppの中身----------------*/
#include "Character.h"
int main(){
using namespace std;
// Characterクラスの実体「karasawa」を作成
Character* karasawa = new Character("唐沢", 10, 2);
// 唐沢のSTRを255に変更
karasawa->STR = 255; //【エラー:karasawa->STRを参照できない】
karasawa->Damage(5); // 唐沢に5ダメージ
// 唐沢のHPを表示
cout << "HP:" << karasawa->HP << endl; //【エラー:karasawa->HPを参照できない】
delete karasawa; //「karasawa」を削除
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クラスの実体「karasawa」を作成
Character* karasawa = new Character("唐沢", 10, 2);
// 唐沢のSTRを255に変更
karasawa->SetSTR(255); // STRのセッター SetSTR を呼ぶ
karasawa->Damage(5); // 唐沢に5ダメージ
// 唐沢のHPを表示
cout << "HP:" << karasawa->GetHP() << endl; // HPのゲッター GetHP を呼ぶ
delete karasawa; //「karasawa」を削除
return 0;
}
セッターとゲッターを使ってprivate変数にアクセスしています。
回りくどく感じると思いますが、どうしてもprivate変数にアクセスしたい場合はこれを使いましょう。
**セッターゲッターの罠
ゲッターは変数の内容を参照するだけなので多少あっても問題はないですが、
セッターは内容を書き換えることができてしまうので&bold(){極力避けるべきです}。
&bold(){また、一つの変数にセッターゲッターを両方用意するのは絶対に避けてください。}
セッターゲッター両方用意すると実質publicになってしまいます。
セッターやゲッター内で特別な処理をしている場合はこれに限りません
*アクセス制御
**アクセス修飾子
オブジェクトのメンバはアクセス制限をする事ができます。
|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;
}
基本的には、&bold(){変数はprivate} &bold(){関数はpublic}に指定します。
//**カプセル化
//クラスを利用する側にとって必要のないメンバは隠すべきです。
//これをカプセル化と言います。
//オブジェクト指向の考え方は、オブジェクト同士のメッセージのやりとりである
//というものがあります。
//メンバ変数を直接読み書きすることはこれに反します。
//オブジェクトは外部のメッセージを受けて動作するものです。
//つまりメンバ変数は隠し
//外部からできる動作のみ公開するべきです。
**メンバ変数の読み書き
不正アクセス対策上の理由で、メンバ変数は基本的に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変数にアクセスしたい場合はこれを使いましょう。
**セッターゲッターの罠
ゲッターは変数の内容を参照するだけなので多少あっても問題はないですが、
セッターは内容を書き換えることができてしまうので&bold(){極力避けるべきです}。
&bold(){また、一つの変数にセッターゲッターを両方用意するのは絶対に避けてください。}
セッターゲッター両方用意すると実質publicになってしまいます。
セッターやゲッター内で特別な処理をしている場合はこれに限りません
表示オプション
横に並べて表示:
変化行の前後のみ表示: