アクセス制御は、カプセル化とクラスの内部データの保護を確保するためのOOPの基本原則です。
問題の歴史:
従来のC++は、3つのアクセス修飾子をサポートしています: public、protected、private。このアイデアは、クラスの内部実装を保護し、インターフェースと実装を分離するために生まれました。
問題:
適切なアクセス制御がないと、クラスのユーザーはオブジェクトの内部状態を意図せず変更したり、クラスの不変条件を破ったりする可能性があります。不適切に設計されたアクセスは、コードの保守とスケーリングを困難にします。
解決策:
外部の世界が使用できるものと、オブジェクトの内部目的のためのものとの間に明確な分離を行うために修飾子を使用します。
コード例:
class Sample { private: int secret; protected: void setSecret(int s) { secret = s; } public: Sample(int s) : secret(s) {} int getSecret() const { return secret; } };
主な特徴:
protected にのみアクセス可能(private にはアクセス不可)。friend関数またはfriendクラスは他のクラスのprivateメンバーにアクセスできますか?
はい、friend キーワードはクラスのプライベートおよび保護されたメンバーへの完全なアクセスを提供します。このアプローチは、カプセル化を破らないように非常に注意して使用する必要があります。
例:
class PrivData { private: int secret; friend void accessSecret(const PrivData& d); }; void accessSecret(const PrivData& d) { std::cout << d.secret; }
名前を知っている場合、ポインタやキャストを使ってprivateメンバーにアクセスできますか?
はい、型キャストやメモリ操作(例:"pointer-to-member trick")を利用することが可能ですが、これは言語の標準を破り、未定義の動作を引き起こします。これは避けるべきです。
継承時に、親クラスのprivateメンバーは子クラスにアクセス可能になりますか?
いいえ、privateメンバーは派生クラスから直接アクセスできません。アクセスは基本クラスのpublic/protectedメソッドを介してのみ可能です。
ネガティブケース
大規模なプロジェクトで、すべてのクラスメンバーがプロトタイピングの迅速化のためにpublicとして宣言されました。
利点:
欠点:
ポジティブケース
すべてのアクセスレベルが厳格に分かれており、friend関数は単体テストのみに使用されています。
利点:
欠点: