回答:
プライベートメンバーは、それらを定義するクラス内でのみアクセスできます。
保護されたメンバーは、それらを定義するクラスおよびそのクラスから継承するクラスでアクセスできます。
編集:どちらも、クラスの友達がアクセスできます。保護されたメンバーの場合は、派生クラスの友達もアクセスできます。
編集2:問題のコンテキストで意味のあるものを使用します。結合を減らして基本クラスの実装を保護するために、できる限りメンバーをプライベートにしようとする必要がありますが、それが不可能な場合は、保護されたメンバーを使用してください。この問題についての理解を深めるには、C ++ FAQを確認してください。保護された変数に関するこの質問も役立つかもしれません。
クラスAのパブリックメンバーは、誰でもアクセスできます。
クラスAの保護されたメンバーは、Aのコードの外部からはアクセスできませんが、Aから派生したクラスのコードからはアクセスできます。
クラスAのプライベートメンバーは、Aのコードの外部、またはAから派生したクラスのコードからはアクセスできません。
したがって、最終的には、保護されたものかプライベートなものかを選択することで、次の質問に答えることができます。
デフォルトでは、派生クラスを信頼しないと想定し、メンバーを非公開にします。派生クラスへの母クラスの内部への無料アクセスを与える非常に正当な理由がある場合、それらを保護することができます。
the protected data of the base class is part of the data of the derived class.
確かに。では、派生クラスの作成者が自分のクラスではなく自分のクラスでそのデータを宣言するようにした方がいいのではないでしょうか。...:-) ... The writer of the derived class is expected to handle this data properly or it is a bug.
NVIパターンの目的は、メソッド、派生クラスのライターが階層に与えるダメージを制限します。保護されたメソッドはすでに潜在的な問題です。保護された状態を使用してこれを悪化させることが正しいアプローチであると私は確信していません。
保護されたメンバーには、派生クラスからアクセスできます。プライベートのものはできません。
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
};
「ベストプラクティス」に関しては、状況によって異なります。誰かが既存のクラスから新しいクラスを派生させ、内部メンバーへのアクセスを必要とする可能性があるかすかな可能性さえある場合は、プライベートではなく保護します。それらがプライベートの場合、クラスを簡単に継承するのが難しくなる可能性があります。
それはすべて、何をしたいか、そして派生クラスが何を見たいかによって異なります。
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(); // wont work
protFunc(); // will work
publFunc(); // will return 1 since it's overridden in this class
}
}
マークされた属性とメソッド(protected
プライベートのものとは異なり)は、依然としてサブクラスで表示されます。
可能なサブクラスでメソッドをオーバーライドする可能性を使用または提供したくない場合を除き、私はそれらを作成しますprivate
。
もちろん、保護されたメンバー変数の質問を見てください。class
結合を減らすために、(C ++ sesと同じように)プライベートをデフォルトとして使用することをお勧めします。保護されたメンバー変数は、常に悪い考えです。保護されたメンバー関数は、たとえばテンプレートメソッドパターンに使用できます。
保護されたメンバーには、クラスの子孫、および同じモジュール内のコードによってのみアクセスできます。プライベートメンバーには、それらが宣言されているクラスと、同じモジュール内のコードによってのみアクセスできます。
もちろん、フレンド関数はこれをウィンドウの外に出しますが、まあ。
プライベートメンバーにはクラス内からのみアクセスでき、保護されたメンバーにはクラスおよび派生クラスからアクセスできます。これはオブジェクト指向言語の継承機能です。
C ++でプライベート、保護、パブリックの継承を設定できます。これにより、継承階層でアクセスできる派生クラスが決まります。たとえば、C#にはパブリック継承のみがあります。
private
メンバーデータには推奨されます。C ++クラスのメンバーはprivate
デフォルトでです。
public
意見の問題ですが、メンバー関数には推奨されます。少なくともいくつかのメソッドはアクセス可能でなければなりません。public
すべての人がアクセスできます。これは最も柔軟なオプションであり、安全性は最も低くなります。だれでもそれらを使用でき、だれでもそれらを誤用することができます。
private
まったくアクセスできません。誰もクラスの外では使用できませんし、誤用することもできません。派生クラスにもありません。
protected
派生クラスで使用できるため、妥協です。クラスから派生するときは、基本クラスをよく理解していて、これらのメンバーを誤用しないように注意します。
MFCは、Windows APIのためのC ++ラッパーです、それは好むpublic
とprotected
。Visual Studioで生成されたクラスは、醜いの混在持っウィザードprotected
、public
およびprivate
メンバーを。しかし、MFCクラス自体にはいくつかのロジックがあります。
などのメンバーSetWindowText
はpublic
、これらのメンバーにアクセスする必要があることが多いためです。
などのメンバーOnLButtonDown
は、ウィンドウが受け取った通知を処理します。これらはアクセスされるべきではないため、アクセスされますprotected
。これらの関数をオーバーライドするために、派生クラスでそれらに引き続きアクセスできます。
一部のメンバーはスレッドとメッセージループを実行する必要があります。これらのメンバーにはアクセスまたはオーバーライドしないでください。そのため、次のように宣言されています。 private
C ++構造では、メンバーはpublic
デフォルトです。構造体は通常、メソッドではなくデータのみに使用されるため、public
宣言は安全と見なされます。
private
はVisual Studioのデフォルトです。それはだprivate
、それは決していないだけでなく、GCCではデフォルトでpublic
、デフォルトで。私が再び間違っていない限り。参照している規格が見つかりません。
プライベート:アクセス指定子です。デフォルトでは、インスタンス(メンバー)変数またはc ++ / javaのクラスのメソッドはプライベートです。継承中、コードとデータは常に継承されますが、クラスの外部からはアクセスできません。データメンバーをプライベートとして宣言して、メンバー変数を直接変更できないようにし、プライベートメンバーを変更するためのパブリックゲッターとセッターを提供することができます。そして、この概念は常にビジネスルールに適用されます。
保護:アクセス指定子でもあります。C ++では、保護されたメンバーはクラス内および継承されたクラスにアクセスできますが、クラスの外部にはアクセスできません。Javaでは、保護されたメンバーは、クラス内、継承されたクラス、および同じパッケージ内のすべてのクラスにアクセスできます。
Private:クラスメンバー関数とフレンド関数またはフレンドクラスからアクセスできます。C ++クラスの場合、これはデフォルトのアクセス指定子です。
保護:クラスメンバー関数、フレンド関数、フレンドクラスと派生クラスからアクセスできます。
プライベートおよび保護されたアクセス修飾子は、基本クラスの保護されたメンバーが子(派生)クラスの基本クラスのスコープ外でアクセスできることと同じです。継承についても同様です。ただし、プライベート修飾子を使用すると、基本クラスのメンバーには、基本クラスのスコープまたはコードとそのフレンド関数でのみアクセスできます '' ''