C++クラスのメンバーprivate
とメンバーの違いは何ですか?protected
クラス外で呼び出されない変数と関数を作成する必要があることは、ベスト プラクティスの慣習から理解していますがprivate
、私の MFC プロジェクトを見ると、MFC は を支持しているようprotected
です。
違いは何ですか?どちらを使用する必要がありますか?
プライベート メンバーは、それらを定義するクラス内でのみアクセスできます。
保護されたメンバーは、それらを定義するクラスおよびそのクラスから継承するクラスでアクセスできます。
編集: どちらも、クラスのフレンドからもアクセスできます。また、保護されたメンバーの場合は、派生クラスのフレンドからもアクセスできます。
編集 2: 問題のコンテキストで意味のあるものを使用してください。結合を減らして基本クラスの実装を保護するために、できる限りメンバーをプライベートにするようにしてください。それが不可能な場合は、保護されたメンバーを使用してください。問題をよりよく理解するには、C++ FAQを確認してください。保護された変数に関するこの質問も役立つ場合があります。
クラス A のパブリックメンバーは、すべてのユーザーがアクセスできます。
クラス A の保護されたメンバーは、A のコードの外部からはアクセスできませんが、A から派生したクラスのコードからはアクセスできます。
クラス A のプライベートメンバーは、A のコードの外部、または A から派生したクラスのコードからはアクセスできません。
したがって、最終的には、保護するかプライベートにするかを選択することは、次の質問への回答となります:派生クラスのプログラマーをどの程度信頼しますか?
デフォルトでは、派生クラスは信頼できないと想定し、メンバーを private にします。マザー クラスの内部構造をその派生クラスに自由にアクセスできる十分な理由がある場合は、それらを保護することができます。
保護されたメンバーは、派生クラスからアクセスできます。私立はできません。
class Base {
private:
int MyPrivateInt;
protected:
int MyProtectedInt;
public:
int MyPublicInt;
};
class Derived : Base
{
public:
int foo1() { return MyPrivateInt;} // Won't compile!
int foo2() { return MyProtectedInt;} // OK
int foo3() { return MyPublicInt;} // OK
};
class Unrelated
{
private:
Base B;
public:
int foo1() { return B.MyPrivateInt;} // Won't compile!
int foo2() { return B.MyProtectedInt;} // Won't compile
int foo3() { return B.MyPublicInt;} // OK
};
「ベストプラクティス」に関しては、状況によります。誰かが既存のクラスから新しいクラスを派生させ、内部メンバーへのアクセスを必要とする可能性がわずかでもある場合は、プライベートではなく、Protected にします。それらがプライベートである場合、クラスは簡単に継承することが難しくなる可能性があります。
MFC が保護を好む理由は、それがフレームワークであるためです。おそらく、MFC クラスをサブクラス化する必要があり、その場合、クラスの一般的な使用には見えないメソッドにアクセスするために、保護されたインターフェイスが必要です。
それはすべて、何をしたいのか、派生クラスに何を見せたいのかによって異なります。
class A
{
private:
int _privInt = 0;
int privFunc(){return 0;}
virtual int privVirtFunc(){return 0;}
protected:
int _protInt = 0;
int protFunc(){return 0;}
public:
int _publInt = 0;
int publFunc()
{
return privVirtFunc();
}
};
class B : public A
{
private:
virtual int privVirtFunc(){return 1;}
public:
void func()
{
_privInt = 1; // wont work
_protInt = 1; // will work
_publInt = 1; // will work
privFunc(); // wont work
privVirtFunc(); // will work, simply calls the derived version.
protFunc(); // will work
publFunc(); // will return 1 since it's overridden in this class
}
}
とマークされた属性とメソッドはprotected
、非公開のものとは異なり、サブクラスで引き続き表示されます。
可能なサブクラスでメソッドをオーバーライドする可能性を使用または提供したくない場合を除き、私はそれらを作成しますprivate
。
保護されたメンバー変数の質問をご覧ください。結合を減らすために、(C++ class
ses と同様に) デフォルトとしてプライベートを使用することをお勧めします。保護されたメンバー変数は、ほとんどの場合、悪い考えです。保護されたメンバー関数は、テンプレート メソッド パターンなどに使用できます。
保護されたメンバーには、クラスの子孫、および同じモジュール内のコードのみがアクセスできます。プライベート メンバーは、それらが宣言されているクラス、および同じモジュール内のコードによってのみアクセスできます。
もちろん、フレンド関数はこれを無視しますが、まあまあです。
プライベート メンバーはクラス内からのみアクセスでき、保護されたメンバーはクラスおよび派生クラスでアクセスできます。オブジェクト指向言語の継承の機能です。
C++ では、プライベート、プロテクト、およびパブリックの継承を行うことができます。これにより、継承階層でどの派生クラスがアクセスできるかが決まります。たとえば、C# にはパブリック継承しかありません。
private = マザーシップ (基本クラス) のみがアクセス可能 (つまり、私の親だけが私の親の寝室に入ることができます)
protected = マザーシップ (基本クラス) とその娘 (つまり、親の寝室に入ることができるのは親だけですが、息子/娘には親の寝室に入る許可を与えました) からアクセス可能
public = マザーシップ (基本クラス)、娘、その他全員がアクセス可能 (つまり、親の寝室に入ることができるのは親だけですが、これはハウス パーティーです - mi casa su casa)
派生クラスで保護されたメンバーをフェッチして更新するためにパブリック メンバー関数が必要ないため、これによりコードの効率が向上し、記述する必要があるコードの量が削減されます。ただし、派生クラスのプログラマーは、自分が何をしているのかを認識しているはずです。
Private : アクセス指定子です。デフォルトでは、c++/java のインスタンス (メンバー) 変数またはクラスのメソッドはプライベートです。継承中、コードとデータは常に継承されますが、クラス外ではアクセスできません。誰もメンバー変数を直接変更できないようにデータ メンバーをプライベートとして宣言し、プライベート メンバーを変更するためにパブリック ゲッターとセッターを提供できます。そして、この概念は常にビジネス ルールに適用されます。
Protected : アクセス指定子でもあります。C++ では、保護されたメンバーは、クラス内および継承されたクラスからアクセスできますが、クラス外ではアクセスできません。Java では、クラス内、継承されたクラス、および同じパッケージ内のすべてのクラスから、保護されたメンバーにアクセスできます。
プライベート メンバーは、宣言されている同じクラスでのみアクセスできます。保護されたメンバーは、それによって継承されるクラスと共に宣言されているクラスでアクセスできます。
保護された非静的基本クラス メンバーには、次のいずれかを使用して、その基本クラスから派生した任意のクラスのメンバーおよびフレンドがアクセスできます。
private および protected アクセス修飾子は、基本クラスの保護されたメンバーが、子 (派生) クラスの基本クラスのスコープ外でアクセスできるという点だけが同じです。継承についても同様です。ただし、private 修飾子を使用すると、基本クラスのメンバーは、基本クラスのスコープまたはコード内でのみアクセスでき、そのフレンド関数のみにアクセスできます。