web-dev-qa-db-ja.com

非公開および保護されたメンバー:C ++

クラスのprivateメンバーとprotectedメンバーの違いについて私に教えてもらえますか?

ベストプラクティスの慣習から、クラスの外で呼び出されない変数や関数はprivateにするべきだと理解しています - しかし私のMFC project、MFCを見てください。protectedを支持しているようです。

違いは何ですか?どちらを使用すればよいですか?

245
Konrad

非公開メンバーは、それを定義するクラス内でのみアクセス可能です。

保護されたメンバーは、それらを定義するクラス内およびそのクラスから継承するクラス内でアクセス可能です。

編集:どちらも彼らのクラスの友人によって、そして保護されたメンバーの場合には、彼らの派生クラスの友人によってもアクセス可能です。

編集2:あなたの問題の文脈の中で理にかなっているものなら何でも使ってください。結合を減らして基本クラスの実装を保護することができるときはいつでもメンバーを非公開にするようにしてください。それが不可能な場合は、保護されたメンバーを使用します。問題の理解を深めるために、 C++ FAQ をチェックしてください。 保護された変数に関するこの質問 も役に立つかもしれません。

337
Firas Assaad

クラスAのパブリックメンバーは、すべての人がアクセスできます。

クラスAの保護されたメンバーは、Aのコード外からはアクセスできませんが、Aから派生したクラスのコードからはアクセスできます。

クラスAの非公開メンバーは、Aのコード外、またはAから派生したクラスのコードからはアクセスできません。

ですから、結局、protectedかprivateかを選ぶことは、次の質問に答えることです。派生クラスのプログラマにどれだけの信頼を入れたいと思いますか?

デフォルトでは、派生クラスは信頼されないと仮定し、あなたのメンバーを非公開にします。あなたがその派生クラスへのマザークラスの内部の自由なアクセスを与える非常に良い理由があるなら、あなたはそれらを保護することができます。

126
paercebal

保護されたメンバーは派生クラスからアクセスできます。個人的なものはできません。

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
};

「ベストプラクティス」の観点では、それは異なります。既存のクラスから新しいクラスを派生させたい場合や、内部メンバーへのアクセスを必要とする可能性がある場合でも、そのメンバーを非公開ではなく保護にします。プライベートの場合、あなたのクラスは簡単に継承できなくなるかもしれません。

58
Roddy

MFCが保護されている理由は、それがフレームワークだからです。おそらくMFCクラスをサブクラス化したい場合があります。その場合、クラスの一般的な使用には見えないメソッドにアクセスするには、保護されたインターフェイスが必要です。

21
Toon Krijthe

それはすべてあなたが何をしたいのか、そして派生クラスに何を見せたいのかにかかっています。

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
    }
}
8

protectedとマークされた属性とメソッドは、プライベートクラスとは異なり、サブクラスにも表示されます。

サブクラスでメソッドをオーバーライドする可能性を使用したくない場合を除き、それらをprivateにします。

5
fhe

確かに 保護されたメンバー変数 の質問を見てください。カップリングを減らすために、C++のclasssesと同じように、デフォルトとしてprivateを使用することをお勧めします。保護されたメンバ変数はほとんどの場合悪い考えです。テンプレートメソッドパターン。

4
xtofl

保護されたメンバは、そのクラスの子孫、および同じモジュール内のコードによってのみアクセス可能です。非公開メンバーには、宣言されているクラス、および同じモジュール内のコードによってのみアクセスできます。

もちろん、フレンド関数はこれをウィンドウの外に出しますが、まあまあです。

非公開メンバーはクラス内からのみアクセス可能であり、保護メンバーはクラスおよび派生クラス内でアクセス可能です。これはOO言語の継承の機能です。

C++では、プライベート、プロテクト、パブリックの継承を持つことができます。これにより、継承階層でどの派生クラスがアクセスできるかが決まります。例えばC#はパブリック継承のみを持ちます。

4
PhilGriffin

private=マザーシップ(基本クラス)のみがアクセス可能(すなわち、私の両親のみが私の両親の寝室に入ることができます)

protected= mothership(base class)でアクセス可能、そして彼女の娘(すなわち、私の両親のみが私の両親の寝室に入ることができますが、息子/娘には許可)両親の寝室に入る)

public= mothership(ベースクラス)、娘、そして他の皆がアクセス可能(つまり、私の両親だけが私の両親の寝室に入ることができますが、それは家のパーティーです) - mi casa su casa)

3
Johan K. Rhodes

派生クラスの保護されたメンバーを取得および更新するためにパブリックメンバー関数は必要ないため、これによってコードの効率が向上し、記述する必要があるコードの量が減ります。しかし、派生クラスのプログラマーは、自分がしていることを知っているはずです。

2
null

メンバーデータにはprivateが推奨されます。 C++クラスのメンバはデフォルトでprivateです。

publicはメンバー関数には好まれますが、意見の問題です。少なくともいくつかのメソッドはアクセス可能でなければなりません。 publicはすべての人にアクセス可能です。それは最も柔軟な選択肢で最も安全性が低いです。誰でもそれらを使用することができ、誰でもそれらを誤用することができます。

privateはまったくアクセスできない。誰もそれらをクラスの外で使用することはできず、誰もそれらを誤用することはできません。派生クラスにもありません。

protectedは派生クラスで使用される可能性があるため妥協です。クラスから派生するときは、基本クラスをよく理解しているので、これらのメンバーを誤用しないように注意してください。

MFCはWindows API用のC++ラッパーです。publicprotectedが優先されます。 Visual Studioウィザードによって生成されたクラスには、protectedpublic、およびprivateのメンバーが見にくく混じっています。ただし、MFCクラス自体にはいくつかのロジックがあります。

SetWindowTextなどのメンバーは、これらのメンバーにアクセスする必要があることが多いのでpublicです。

OnLButtonDownなどのメンバーは、ウィンドウによって受信された通知を処理します。それらはアクセスされるべきではないので、それらはprotectedです。派生クラスでそれらにアクセスして、これらの関数をオーバーライドすることができます。

何人かのメンバーはスレッドとメッセージループをしなければなりません、それらはアクセスされるべきではなく、オーバーライドされるべきではないので、彼らはprivateとして宣言されます

C++構造体では、メンバはデフォルトでpublicです。構造体は通常、メソッドではなくデータ専用に使用されるため、public宣言は安全と見なされます。

1
  • Private:アクセス指定子です。デフォルトでは、c ++/Javaのインスタンス(メンバー)変数またはクラスのメソッドはプライベートです。継承中、コードとデータは常に継承されますが、クラスの外からはアクセスできません。データ変数を非公開として宣言することで、メンバー変数を直接変更することはできず、非公開メンバーを変更するためにパブリックゲッターとセッターを提供することができます。そして、この概念は常にビジネスルールに適用されます。

  • 保護:アクセス指定子でもあります。 C++では、保護されたメンバーはクラス内および継承クラスにアクセスできますが、クラス外にはアクセスできません。 Javaでは、保護されたメンバーは、クラス内から継承されたクラス、および同じパッケージ内のすべてのクラスにアクセスできます。

1
Tutu Kumari

非公開メンバーは、それが継承されるクラスと一緒に宣言されるクラスで保護されたメンバーとしてアクセスできる場所と同じクラスでのみ宣言できます。

1
Gayki

保護された非静的基本クラスメンバは、次のいずれかを使用して、その基本クラスから派生した任意のクラスのメンバおよび友達からアクセスできます。

  • 直接的または間接的に派生したクラスへのポインタ
  • 直接または間接派生クラスへの参照
  • 直接派生クラスまたは間接派生クラスのオブジェクト
0
mujtaba

非公開:クラスメンバー関数&フレンド関数またはフレンドクラスでアクセス可能。 C++クラスの場合、これはデフォルトのアクセス指定子です。

保護されたもの:クラスメンバ関数、フレンド関数、またはフレンドクラスと派生クラスによってアクセス可能。

  • 必要に応じて、クラスメンバーの変数や関数(typedefや内部クラスを含む)を非公開にしたり、保護したりすることができます。
  • ほとんどの場合、クラスメンバーを非公開にしてカプセル化するためのget/set関数を追加します。これはコードのメンテナンスに役立ちます。
  • 一般的に私用関数は、あなたがあなたの公開関数をモジュール化しておきたいとき、あるいは単一の関数にコード全体を書く代わりに繰り返しコードを排除したいときに使用されます。これはコードのメンテナンスに役立ちます。

詳しくはこのリンク を参照してください。

0
Darshan Rajgor