C++/アクセス指定子
表示
< C++
アクセス指定子の基礎
[編集]概要
[編集]アクセス指定子は、C++におけるカプセル化と情報隠蔽の主要なメカニズムです。クラスや構造体のメンバー(変数・関数)へのアクセス制御を設定し、以下の目的を達成します:
- データの保護とカプセル化の実現
- クラスインターフェースの明確な定義
- 継承階層における適切なアクセス制御
基本的な指定子
[編集]C++は3種類の基本的なアクセス指定子を提供します:
- public
- * クラス外部から自由にアクセス可能
- * インターフェースの公開に使用
- * 例:クラスのAPIとして公開するメソッド
- private
- * クラス内部からのみアクセス可能
- * データ隠蔽の実現に使用
- * 例:内部実装の詳細、状態管理変数
- protected
- * クラス内部と派生クラスからアクセス可能
- * 継承を考慮した設計に使用
- * 例:派生クラスでオーバーライドされるメソッド
構文と使用法
[編集]class Example { public: void publicMethod(); // 外部からアクセス可能 private: int privateData; // クラス内部のみ protected: virtual void protectedMethod(); // 派生クラスも可 };
モダンC++におけるアクセス制御
[編集]C++17以降の新機能
[編集]インライン変数とstatic constexpr
[編集]class Modern { public: static inline int counter = 0; // C++17: クラス内インライン変数 static constexpr int MAX = 100; // コンパイル時定数 private: inline static int internal = 0; // private なインライン変数 };
構造化束縛とアクセス制御
[編集]class DataHolder { public: auto getData() const { return std::tuple{value1, value2}; } private: int value1 = 0; int value2 = 0; }; // 使用例 auto [v1, v2] = dataHolder.getData();
C++20の拡張
[編集]コンセプトとアクセス制御
[編集]template<typename T> concept Accessible = requires(T t) { { t.publicMethod() } -> std::same_as<void>; }; class Modern { public: void publicMethod() requires Accessible<Modern>; private: void privateMethod(); };
モジュールでのアクセス制御
[編集]// mymodule.cpp export module mymodule; export class Public { // モジュール外部から見える }; class Private { // モジュール内部でのみ見える };
アクセス制御のベストプラクティス
[編集]設計原則
[編集]- デフォルトでprivate
- メンバーは特に理由がない限りprivateにする
- 必要に応じて段階的に公開レベルを上げる
- インターフェースの最小化
- publicメンバーは必要最小限に抑える
- 実装の詳細は完全に隠蔽する
- 継承を考慮した設計
- protectedは慎重に使用する
- 派生クラスに必要な機能のみを公開
パターンと実践例
[編集]PIMPLイディオム
[編集]- PIMPLイディオム(Pointer to Implementation)は、クラスの実装をヘッダーファイルから分離し、プライベートな実装をポインタを通じて管理することで、コンパイル時間の短縮や依存関係の削減を実現する設計パターンです。
// ヘッダーファイル class Widget { public: Widget(); ~Widget(); void doSomething(); private: class Impl; std::unique_ptr<Impl> pimpl; }; // 実装ファイル class Widget::Impl { // 実装の詳細 };
インターフェースクラス
[編集]class IShape { public: virtual ~IShape() = default; virtual double area() const = 0; protected: // 派生クラスで使用する共通機能 virtual void transform() = 0; private: // 実装の詳細 };
アクセス制御の応用
[編集]フレンド宣言
[編集]クラス間の特別なアクセス権を付与します:
class Secretary { friend class Manager; // Managerクラスに特別なアクセス権を付与 private: void accessConfidentialData(); };
テンプレートとアクセス制御
[編集]template<typename T> class Container { public: void add(const T& item); private: std::vector<T> items; using Iterator = typename std::vector<T>::iterator; protected: virtual void onItemAdded(const T& item); };
高度なトピック
[編集]アクセス指定子の継承制御
[編集]継承時のアクセス指定子による影響:
基底クラスのメンバー public継承 protected継承 private継承 public public protected private protected protected protected private private アクセス不可 アクセス不可 アクセス不可
スマートポインタとアクセス制御
[編集]class Resource { public: static std::shared_ptr<Resource> create() { return std::shared_ptr<Resource>(new Resource()); } private: Resource() = default; // 直接のインスタンス化を防ぐ };
まとめ
[編集]アクセス指定子は、C++のカプセル化とデータ隠蔽の中心的なメカニズムです。モダンC++では、より洗練された使用方法と新しい機能が追加され、より柔軟で安全なコード設計が可能になっています。適切なアクセス制御の実装は、保守性が高く、拡張しやすいコードの作成に不可欠です。