継承に関するアクセス修飾子の意味について混乱しています。 private
、protected
、およびpublic
キーワードを含む継承の違いは何ですか?
3 access specifiers
C++のクラス/構造体/ユニオンの場合。これらのアクセス指定子は、クラスのメンバーにアクセスする方法を定義します。もちろん、クラスのメンバーはそのクラス内でアクセスできます(同じクラスのメンバー関数内)。アクセス指定子のタイプに進むと、次のとおりです。
Public-Publicとして宣言されたメンバーは、クラスのオブジェクトを通じてクラスの外部からアクセスできます。
Protected-Protectedとして宣言されたメンバーは、クラスの外部からアクセスできます[〜#〜] but [〜#〜 ]派生クラスのみ。
Private-これらのメンバーは、クラス内からのみアクセスできます。外部アクセスは許可されていません。
ソースコードの例:
class MyClass
{
public:
int a;
protected:
int b;
private:
int c;
};
int main()
{
MyClass obj;
obj.a = 10; //Allowed
obj.b = 20; //Not Allowed, gives compiler error
obj.c = 30; //Not Allowed, gives compiler error
}
C++の継承は、次のいずれかのタイプになります。
Private
継承Public
継承Protected
inheritanceこれらのそれぞれに関するメンバーアクセスルールは次のとおりです。
クラスの最初で最も重要なルール
Private
メンバーは、同じクラスのメンバー以外のどこからもアクセスできません。
基本クラスのすべての
Public
メンバーは、派生クラス&のPublic
メンバーになります&
基本クラスのすべてのProtected
メンバーは、派生クラスのProtected
メンバーになります。
つまり、メンバーのアクセスに変更はありません。前に説明したアクセスルールは、さらにこれらのメンバーに適用されます。
コード例:
Class Base
{
public:
int a;
protected:
int b;
private:
int c;
};
class Derived:public Base
{
void doSomething()
{
a = 10; //Allowed
b = 20; //Allowed
c = 30; //Not Allowed, Compiler Error
}
};
int main()
{
Derived obj;
obj.a = 10; //Allowed
obj.b = 20; //Not Allowed, Compiler Error
obj.c = 30; //Not Allowed, Compiler Error
}
基本クラスの
Public
メンバーはすべて、派生クラスのPrivate
メンバーになります&
基本クラスのすべてのProtected
メンバーは、派生クラスのPrivate
メンバーになります。
コード例:
Class Base
{
public:
int a;
protected:
int b;
private:
int c;
};
class Derived:private Base //Not mentioning private is OK because for classes it defaults to private
{
void doSomething()
{
a = 10; //Allowed
b = 20; //Allowed
c = 30; //Not Allowed, Compiler Error
}
};
class Derived2:public Derived
{
void doSomethingMore()
{
a = 10; //Not Allowed, Compiler Error, a is private member of Derived now
b = 20; //Not Allowed, Compiler Error, b is private member of Derived now
c = 30; //Not Allowed, Compiler Error
}
};
int main()
{
Derived obj;
obj.a = 10; //Not Allowed, Compiler Error
obj.b = 20; //Not Allowed, Compiler Error
obj.c = 30; //Not Allowed, Compiler Error
}
基本クラスのすべての
Public
メンバーは、派生クラス&のProtected
メンバーになります&
基本クラスのすべてのProtected
メンバーは、派生クラスのProtected
メンバーになります。
コード例:
Class Base
{
public:
int a;
protected:
int b;
private:
int c;
};
class Derived:protected Base
{
void doSomething()
{
a = 10; //Allowed
b = 20; //Allowed
c = 30; //Not Allowed, Compiler Error
}
};
class Derived2:public Derived
{
void doSomethingMore()
{
a = 10; //Allowed, a is protected member inside Derived & Derived2 is public derivation from Derived, a is now protected member of Derived2
b = 20; //Allowed, b is protected member inside Derived & Derived2 is public derivation from Derived, b is now protected member of Derived2
c = 30; //Not Allowed, Compiler Error
}
};
int main()
{
Derived obj;
obj.a = 10; //Not Allowed, Compiler Error
obj.b = 20; //Not Allowed, Compiler Error
obj.c = 30; //Not Allowed, Compiler Error
}
同じアクセスルールが継承階層の下のクラスとメンバーに適用されることに注意してください。
-アクセス仕様はオブジェクトごとではなくクラスごとです
アクセス仕様C++は、オブジェクトごとではなく、クラスごとに機能することに注意してください。
これの良い例は、コピーコンストラクターまたはコピー割り当て演算子関数で、渡されるオブジェクトのすべてのメンバーにアクセスできることです。
-派生クラスは、自身の基本クラスのメンバーにのみアクセスできます
次のコード例を考慮してください:
class Myclass
{
protected:
int x;
};
class derived : public Myclass
{
public:
void f( Myclass& obj )
{
obj.x = 5;
}
};
int main()
{
return 0;
}
コンパイルエラーが発生します。
prog.cpp:4:エラー:「int Myclass :: x」は保護されています
派生クラスは、その独自の基本クラスのメンバーにのみアクセスできるためです。ここで渡されるオブジェクトobj
は、アクセスされるderived
クラス関数とはまったく関係がなく、まったく異なるオブジェクトであり、したがってderived
メンバー関数であることに注意してください。メンバーにアクセスできません。
friend
とは何ですか? friend
はアクセス仕様ルールにどのように影響しますか?関数またはクラスを別のクラスのfriend
として宣言できます。その場合、アクセス仕様ルールはfriend
edクラス/関数に適用されません。クラスまたは関数は、その特定のクラスのすべてのメンバーにアクセスできます。
だから、
friend
sはカプセル化を壊しますか?
いいえ、そうではありませんが、逆にカプセル化を強化します!
friend
shipは、2つのエンティティ間の意図的な強い結合を示すために使用されます。
2つのエンティティ間に特別な関係があり、一方が他のprivate
またはprotected
メンバーにアクセスする必要があるが、必要ない場合everyonepublic
アクセス指定子を使用してアクセスするには、friend
shipを使用する必要があります。
Effective C++のScott Meyersからの説明は、それらをいつ使用するかを理解するのに役立つかもしれません。
パブリック継承は「is-a関係」をモデル化する必要がありますが、プライベート継承は「is-implemented-in-terms-of」に使用する必要があります。そのため、スーパークラスのインターフェースに従う必要はなく、再利用するだけです。実装。