C++ データの抽象化


データ抽象化とは、重要な情報のみを外部に提供し、そのバックグラウンド実装の詳細を隠すこと、つまり、詳細を提示せずに必要な情報のみを表示することを指します。

データ抽象化は、インターフェイスと実装の分離に依存するプログラミング (設計) 手法です。

テレビのような実際の例を見てみましょう。テレビのオン/オフ、チャンネルの切り替え、音量の調整、外部コンポーネント (スピーカー、VCR、DVD プレーヤーなど) の追加ができますが、内部の実装の詳細、つまり、ケーブル経由で信号をどのように受信し、信号を変換し、最終的に画面に表示するかがわかりません。

したがって、テレビは内部実装と外部インターフェースを分離していると言えます。内部実装原理を知る必要はなく、外部インターフェース (電源ボタン、リモコン、音量コントローラーなど) テレビを通じて直接制御できます。 。

さて、本題に入りましょう。C++ プログラミングに関する限り、C++ クラスは データ抽象化 の可能性を提供します。これらは、オブジェクト データを操作するためのパブリック メソッドを外部の世界に多数提供します。つまり、外部の世界は実際にはクラスの内部実装を知りません。

たとえば、関数内のデータの並べ替えに使用されるアルゴリズムを知らなくても、プログラムは sort() 関数を呼び出すことができます。実際、関数ソートの基礎となる実装はライブラリのバージョンに応じて異なります。インターフェイスが変更されていない限り、関数呼び出しは通常どおり機能します。

C++ では、クラスを使用して独自の抽象データ型 (ADT) を定義します。以下に示すように、クラス ostreamcout オブジェクトを使用して、データを標準出力に出力できます。

#include <iostream>
using namespace std;

int main( )
{
   cout << "Hello C++" <<endl;
   return 0;
}

ここでは、cout がユーザーの画面にテキストを表示する方法を理解する必要はありません。パブリック インターフェイスについて知っていれば十分です。cout の基礎となる実装は自由に変更できます。

アクセス タグは抽象化を強制します

C++ では、アクセス タグを使用してクラスの抽象インターフェイスを定義します。クラスには 0 個以上のアクセス タグを含めることができます。

  • public タグで定義されたメンバーは、プログラムのすべての部分にアクセスできます。型のデータの抽象ビューは、そのパブリック メンバーによって定義されます。

  • プライベートタグを使用して定義されたメンバーは、クラスを使用してコードにアクセスできません。プライベート部分は、その型を使用するコードから実装の詳細を隠します。

アクセスタグの頻度に制限はありません。各アクセス タグは、それに続くメンバー定義のアクセス レベルを指定します。指定されたアクセス レベルは、次のアクセス タグに遭遇するか、クラス本体の右閉じ括弧に遭遇するまで有効です。

データ抽象化の利点

データ抽象化には 2 つの重要な利点があります:

  • クラスの内部は、意図しないユーザーレベルのエラーによるオブジェクトの状態の破損から保護されます。

  • クラスの実装は、要件の変化に応じて、またはユーザーレベルのコードの変更を必要としないバグレポートに応じて、時間の経過とともに変更される場合があります。

クラスのプライベート部分にのみデータメンバーを定義すると、クラスの作成者はデータを自由に変更できます。実装が変更された場合、クラスのコードをチェックするだけで、この変更がどのような影響を与えるかを確認できます。データがパブリックである場合、古い表現のデータ メンバーに直接アクセスする関数が影響を受ける可能性があります。

データ抽象化のインスタンス

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

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

設計戦略

抽象化では、コードをインターフェイスと実装に分離します。したがって、コンポーネントを設計するときは、基になる実装が変更されてもインターフェイスが変更されないように、インターフェイスを実装から独立させておく必要があります。

この場合、どのプログラムがインターフェイスを使用しても、インターフェイスは影響を受けず、最新の実装のみを再コンパイルする必要があります。