C++ データカプセル化

データカプセル化(Data Encapsulation)は、オブジェクト指向プログラミング(OOP)の基本概念の一つであり、データとそのデータを操作する関数をクラス内にカプセル化することによって実現されます。このカプセル化により、データの非公開性と完全性が保証され、外部コードによる直接アクセスや変更が防止されます。

すべてのC++プログラムには、次の2つの基本要素があります。

  • プログラム文(コード):これはプログラム内で動作を実行する部分であり、関数と呼ばれます。
  • プログラムデータ:データはプログラムの情報であり、プログラムの関数の影響を受けます。

カプセル化は、オブジェクト指向プログラミングにおいて、データとデータを操作する関数を結び付ける概念であり、外部からの干渉や誤用を避け、安全性を確保します。データカプセル化から、もう一つの重要なOOP概念が導き出されます。すなわち、データ隠蔽。

データカプセル化は、データとデータを操作する関数を結び付けるメカニズムです。データ抽象化は、ユーザーにインターフェースのみを公開し、具体的な実装の詳細を隠すメカニズムです。

C++は作成することによって类カプセル化とデータ隠蔽をサポートします(public、protected、private)。すでに知っているように、クラスにはプライベートメンバ(private)、プロテクトメンバ(protected)、パブリックメンバ(public)が含まれます。デフォルトでは、クラス内で定義されたすべての項目はプライベートです。例えば:

class Box { public: double getVolume(void) { return length * breadth * height; } private: double length; // 長さ double breadth; // 幅 double height; // 高さ };

変数 length、breadth、height はすべてプライベート(private)です。つまり、これらは Box クラスの他のメンバからのみアクセスでき、プログラムの他の部分からはアクセスできません。これはカプセル化を実現する一つの方法です。

クラスのメンバをパブリックにする(つまり、プログラムの他の部分からもアクセスできるようにする)には、これらのメンバの前にpublicキーワードを付けて宣言する必要があります。public 識別子の後に定義されたすべての変数または関数は、プログラム内の他のすべての関数からアクセスできます。

あるクラスを別のクラスのフレンドクラスとして定義すると、実装の詳細が公開され、カプセル化が低下します。理想的な方法は、各クラスの実装の詳細を可能な限り外部に隠すことです。

アクセス修飾子:

  • private: プライベートメンバはクラス内部からのみアクセスでき、クラスの外部コードから直接アクセスすることはできません。
  • public: パブリックメンバはクラスの外部コードから直接アクセスできます。
  • protected: プロテクトメンバはクラスおよびその派生クラスからアクセスできます。

データカプセル化の例

C++ プログラムにおいて、パブリックメンバとプライベートメンバを持つ任意のクラスは、データカプセル化とデータ抽象化の例と見なすことができます。次の例を見てください。

例

#include <iostream> using namespace std; class Adder{ public: // コンストラクタ Adder(int i = 0) { total = i; } // 外部向けインターフェース void addNum(int number) { total += number; } // 外部向けインターフェース int getTotal() { return total; }; private: // 外部に隠されたデータ int total; }; int main( ) { Adder a; a.addNum(10); a.addNum(20); a.addNum(30); cout << "Total " << a.getTotal() <<endl; return 0; }

上記のコードをコンパイルして実行すると、次の結果が生成されます。

Total 60

上記のクラスは数値を加算し、合計を返します。パブリックメンバaddNumとgetTotalは外部向けのインターフェースであり、ユーザーはクラスを使用するためにそれらを知る必要があります。プライベートメンバtotalは外部に隠されており、ユーザーが知る必要はありませんが、クラスが正常に動作するために必要です。

データカプセル化は、クラスとアクセス修飾子(public, private, protected)によって実現されます。以下は簡単な例です。

例

#include <iostream>
using namespace std;

class Student {
private:
    string name;
    int age;

public:
    // コンストラクタ
    Student(string studentName, int studentAge) {
        name = studentName;
        age = studentAge;
    }

    // アクセサ関数(getter)
    string getName() {
        return name;
    }

    int getAge() {
        return age;
    }

    // セッター関数(setter)
    void setName(string studentName) {
        name = studentName;
    }

    void setAge(int studentAge) {
        if (studentAge > 0) {
            age = studentAge;
        } else {
            cout << "Invalid age!" << endl;
        }
    }

    // 学生情報を出力
    void printInfo() {
        cout << "Name: " << name << ", Age: " << age << endl;
    }
};

int main() {
    // Student オブジェクトを作成
    Student student1("Alice", 20);

    // データにアクセスして変更
    student1.printInfo();

    student1.setName("Bob");
    student1.setAge(22);

    student1.printInfo();

    return 0;
}

設計戦略

通常、本当に公開する必要がある場合を除いて、クラスメンバの状態をプライベート(private)に設定します。これにより、優れたカプセル化を保証します。。

これは通常データメンバに適用されますが、仮想関数を含むすべてのメンバにも同様に適用されます。

データカプセル化の利点

  • データ隠蔽: データメンバをプライベートとして宣言することで、外部コードがこれらのデータに直接アクセスするのを防ぎます。
  • コードの保守性の向上データにアクセスして変更するためのパブリックメソッドを提供します。これにより、外部コードに影響をとえずにクラスの内部実装を変更できます。
  • セキュリティの強化: 不正なデータ入力や不適切な変更操作を防ぎます。
  • 抽象化の実現: ユーザーがクラスの内部実装の詳細を理解する必要がなく、クラスのパブリックインターフェースの使用方法だけを理解すればよいというメカニズムを提供します。
その他の拡張