前回は クラスの基本的な使い方 について解説しました。
改めて前回の内容をおさらいをしておくと、
———————————————————————————————————
クラスのメンバ関数の処理実装記述をグローバル領域(関数の外の領域)で行う場合、
戻り値のデータ型 クラス名::関数名(引数のデータ型 引数) { //処理記述 }
という順で記述する。
クラス名の後にダブルコロン(::)を記述し、その後に関数名を書くことによって、クラス所属のメンバ関数であることを意味する。
関数の実装記述が、簡易なものであれば、グローバル領域ではなく、クラスの{}内でしても差し支えない(インライン定義)
クラス内の各メンバを呼び出すときには、インスタンスの後に、ドット(.)を書いて呼び出したいメンバを記述する。
———————————————————————————————————
ということをお伝えしました。
今回は アクセス指定子 についてお話ししたいと思います。
アクセス指定子とは?
前回の第49回でも軽く触れましたが、アクセス指定子 というのはクラス内の変数や関数(メンバ)の利用有効範囲(アクセスレベル)を決めるためのものです。
以前、変数にはローカル変数 と グローバル変数 があり、有効範囲に応じて使い分ける事を解説しましたが、アクセス指定子というのは、その有効範囲指定をクラスの各メンバに行うためのものです
(今はまだピンと来なくても全然大丈夫です)
そして、それを決定するのに
という3種類のキーワードを使っていきます。今回は、前回詳しく触れなかった、それぞれのキーワードが決定する有効範囲(アクセスレベル)について、解説していきます。
アクセス指定子その1 -private–
アクセス指定子の1つである、privateキーワードで指定された変数や関数は、その利用有効範囲が宣言したクラスの中に制限されます。
クラス内の関数が、privateキーワードで指定された変数や関数を使うことは許されていますが、それを超えた外部領域からアクセス・利用することは許されていません。
//クラスの宣言
class exampleClass
{
private:
//アクセスレベルprivateのメンバー変数「privateVariable」を宣言
int privateVariable;
}
↑のサンプルコードではアクセスレベル=private、データ型はintのメンバ変数「privateVariable」を宣言しました。
このメンバ変数「privateVariable」にアクセスできるのは、exampleClass内のメンバ関数だけです。↓
//クラスの宣言
class exampleClass
{
private:
//アクセスレベルprivateのメンバー変数「privateVariable」を宣言
int privateVariable;
//アクセスレベルprivateの関数。privateVariableにアクセスすることは可能
int privateFunction(){return privateVariable;};
public:
//アクセスレベルpublicの関数。privateVariableにアクセスすることは可能
int publicFunction(){return privateVariable;};
}
privateFunctionはアクセスレベル=privateのメンバー関数です。
従って、メンバ変数「privateVariable」にアクセスすることは可能です。
publicFunctionはアクセスレベル=publicのメンバ関数です。(publicのアクセスレベルについては後程解説しますのでお待ちください)
従って、メンバ変数「privateVariable」にアクセスすることは可能です。
privateFunction、publicFunctionともにインライン定義で、「privateVariableの値を戻す」という処理実装記述をしています。
↓の動画では、privateFunction、publicFunctionの宣言部分を最初コメントアウトしていたのですが、コメントアウトを消去して順次コンパイルしてもエラーは発生しませんでした。
一方で、宣言したクラスのメンバ関数ではないところから、アクセスをしようとすると当然エラーになります。
//クラスの宣言
class exampleClass
{
private:
//アクセスレベルprivateのメンバー変数「privateVariable」を宣言
int privateVariable;
//アクセスレベルprivateの関数。privateVariableにアクセスすることは可能
int privateFunction(){return privateVariable;};
public:
//アクセスレベルpublicの関数。privateVariableにアクセスすることは可能
int publicFunction(){return privateVariable;};
};
//exampleClassのメンバではない関数からアクセスしようとするとエラーになる。
int independentFunction()
{
return privateVariable;
}
independentFunctionは、exampleClassクラスのメンバではない独立した関数なので、変数「privateVariable」にはアクセスできません。コンパイルしようとするとエラーが発生します。
しかし、↓のサンプルコードのように独立関数ではなく、クラスのメンバ関数になるような記述に書き換えると、エラーにはなりません。
//クラスの宣言
class exampleClass
{
private:
//アクセスレベルprivateのメンバー変数「privateVariable」を宣言
int privateVariable;
//アクセスレベルprivateの関数。privateVariableにアクセスすることは可能
int privateFunction(){return privateVariable;};
public:
//アクセスレベルpublicの関数。privateVariableにアクセスすることは可能
int publicFunction(){return privateVariable;};
//アクセスレベルpublicの関数。
int independentFunction();
};
//グローバル領域にてindependentFunction関数の実装記述→privateVariableにアクセスすることは可能
int exampleClass::independentFunction()
{
return privateVariable;
}
↓の動画では、最初、独立関数からprivateレベルの変数へアクセスさせた後(当然コンパイルエラーになります)、途中で独立関数をメンバ関数に変換する記述をしました。 メンバ関数になったので、privateレベルの変数へのアクセス権が生じ、エラーも解消されたのがわかります。
アクセス指定子その2 -protected-
protectedキーワードで指定された変数や関数は、その利用有効範囲が、宣言したクラスと、派生クラスに制限されます。
派生クラスという概念は、次回一つの項目として解説しますので、詳しいことは今は分からなくて大丈夫です。
宣言したクラスのみでしたので、protectedレベルの変数や関数は、privateよりは有効範囲が広いということです。
//構造体の宣言
class exampleClass
{
protected:
//アクセスレベルprotectedのメンバー変数「protectedVariable」を宣言
int protectedVariable;
};
まずは、アクセスレベル=protectedのメンバ変数「protectedVariable」を宣言しました。
これをたたき台に、アクセスレベルがprotectedの有効範囲を見ていきましょう。
↓の動画では、classFunctionという、メンバ関数を作り、インライン定義によって、メンバ変数「protectedVariable」にアクセスさせています。
アクセスレベルをprivate,protected,publicと都度変更してコンパイルしていますが、エラーは生じていません。クラス外の独立した関数からのアクセスはエラーになっています。ここまではアクセスレベル=privateと同じです。
アクセルレベル privateとprotectedの違い
次のコードを見てください。
//クラスの宣言
class exampleClass
{
//アクセスレベルprivateのメンバー変数「privatedVariable」を宣言
private:
int privatedVariable;
protected:
//アクセスレベルprotectedのメンバー変数「protectedVariable」を宣言
int protectedVariable;
};
//派生クラスの宣言
class derivedClass : public exampleClass
{
public:
int derivedFunction(){return protectedVariable;};
//派生クラスのメンバ関数なので、protectedVariableにアクセスできる
};
exampleClassクラスの派生クラスであるderivedClassを作りました。
派生クラスというのは、その名前の通り、あるクラスから派生したクラスのことです。
先ほど申し上げたように、その意味するところは派生クラスの講座記事でゆっくりやるのでそれをお待ちいただきたいのですが、
classキーワード→ 派生クラス名 →コロン(:) →public 派生元のクラス名
という順で記載することによって、派生クラスを作ることができます。↓
//派生クラスの宣言
class derivedClass : public exampleClass
↓の動画は、exampleClassの派生クラスderivedClassを作り、その中のメンバ関数であるderivedFunctionより、exampleClassのprivate,protectedレベルであるメンバ変数にそれぞれアクセスを試みている所を映したものです。
protectedのメンバ変数にはアクセスできてますが、privateレベルメンバ変数へのアクセスはエラーが発生しているのがわかります。
アクセス指定子その3 -public-
publicキーワードで指定された変数や関数は、クラスの外からでもアクセスできます。
//クラスの宣言
class exampleClass
{
//アクセスレベルpublicのメンバー変数「publicVariable」を宣言
public:
int publicVariable;
void publicFunction();
};
//派生クラスの宣言
void exampleClass::publicFunction()
{
Print(publicVariable);
}
//exampleClassのインスタンスexampleを生成
exampleClass example;
void OnStart()
{
//メンバ変数「publicVariable」の呼び出しと代入
example.publicVariable=1;
//メンバ関数「publicFunction」の呼び出し
example.publicFunction();
}
↓の動画は、サンプルコードを実際に実行したものです。
OnStart関数からexampleインスタンスを通して、publicVariableというメンバ変数とpublicFunctionというメンバ関数を呼び出しています。
クラスでは、アクセスレベル=publicの変数や関数が、プログラムにおいて重要な役割を担うことが多いです。
これまでに、関数を説明する際に家電を例に出してきたのですが、クラスのアクセス指定子についても、家電を例にして説明することができるでしょう。
家電で言えば、
publicは外側から私たちが操作できるボタンであり、
privateやprotectedは家電内部の、私たちが仕組みをよく知らない部品
にあたるでしょう。
家電内部の部品(privateやprotected)には、外側からの操作ボタン(public)を通してしかアクセスができないし、逆に分解して仕組みをよく知らない部品(privateやprotected)を私たちが直接いじるようなことをしたら故障してしまいますね(>_<)
クラスがアクセス指定子でアクセスレベルを設けているのも、プログラムのデリケートな部分をむやみやたらにいじって、エラー・不具合を起こさないためです。
補足
protectedのメンバ変数にアクセスする派生クラスのメンバ関数のアクセスレベルは、 private, protected, public いずれでもOKです。
private,protected,publicで規定しているアクセスレベルは、あくまで「アクセスされる」レベルです。
「アクセスする」側のアクセスレベルについて規定しているものではないので、混同しないように注意してください。
↓の動画では派生元クラスではprotectedレベルの変数に対して、派生クラスのderivedFunction関数がアクセスしているのですが、derivedFunction関数のアクセスレベルをprivate,protected,publicいずれに変えてもprivatedVariableにアクセスできているのがわかるかと思います。
まとめ
今回は アクセス指定子 について解説しました。
今回の記事では以下のことを学びました
- クラス内の変数や関数(メンバ)には、private,protected,publicというアクセスレベルが設けられている。
- privateキーワードで指定された変数や関数は、その利用有効範囲が宣言したクラスの中に制限される。
- protectedキーワードで指定された変数や関数は、その利用有効範囲が、宣言したクラスと、派生クラスに制限される。
- publicキーワードで指定された変数や関数は、クラスの外からでもアクセスできる。
今回は以上になります。
最後までお読みいただきありがとうございました<m(__)m>
【超入門】MQL5 EA講座 第49回「クラスについて2 -クラスの使い方-」【EAの作り方】←
→【超入門】MQL5 EA講座 第51回「クラスについて4 -派生クラス-」【EAの作り方】
※クラスの実際の使用例に関しては、今後の講座記事にはなりますが、以下の記事で解説していますので、今はよくわからなくてもご安心ください。
・MQL5 EA講座 第71回「トレード用のオリジナルクラスを作る」
・MQL5 EA講座 第82回「ポジション情報管理クラスを作る-その1」
・MQL5 EA講座 第83回「ポジション情報管理クラスを作る-その2」
・MQL5 EA講座 第88回「待機注文情報取得用のクラスを追加する」
・MQL5 EA講座 第96回「トレーリングストップクラスを作る1」
コメント