C++ 데이터 추상화


데이터 추상화란 외부에 핵심 정보만 제공하고 배경 구현 세부 사항은 숨기는 것, 즉 세부 사항을 제시하지 않고 필요한 정보만 표시하는 것을 말합니다.

데이터 추상화는 인터페이스와 구현의 분리에 의존하는 프로그래밍(설계) 기술입니다.

TV와 같은 실제 예를 들어보겠습니다. TV를 켜고 끄고, 채널을 전환하고, 볼륨을 조절하고, 외부 구성 요소(스피커, VCR, DVD 플레이어 등)를 추가할 수 있지만 이를 알지 못합니다. 구현 세부 사항, 즉 케이블을 통해 신호를 수신하고 신호를 변환하여 최종적으로 화면에 표시하는 방법을 알 수 없습니다.

따라서 TV는 내부 구현과 외부 인터페이스를 분리한다고 말할 수 있습니다. 내부 구현 원리를 알 필요가 없으며 외부 인터페이스(예: 전원 버튼, 리모컨, 볼륨 컨트롤러)를 통해 TV를 직접 제어할 수 있습니다. .

이제 본격적으로 C++ 프로그래밍에 관한 한 C++ 클래스는 데이터 추상화 가능성을 제공합니다. 이들은 객체 데이터를 외부 세계에 조작하기 위한 다수의 공개 메소드를 제공합니다. 즉, 외부 세계는 실제로 클래스의 내부 구현을 알지 못합니다.

예를 들어, 프로그램은 함수의 데이터를 정렬하는 데 사용되는 알고리즘을 몰라도 sort() 함수를 호출할 수 있습니다. 실제로 함수 정렬의 기본 구현은 라이브러리 버전에 따라 달라집니다. 인터페이스가 변경되지 않는 한 함수 호출은 평소대로 작동합니다.

C++에서는 classes를 사용하여 자체 추상 데이터 유형(ADT)을 정의합니다. 아래와 같이 ostream 클래스의 cout 개체를 사용하여 데이터를 표준 출력으로 출력할 수 있습니다.

#include <iostream>
using namespace std;

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

여기에서는 cout이 사용자 화면에 텍스트를 표시하는 방법을 이해할 필요가 없습니다. 공개 인터페이스만 알면 되며, cout의 기본 구현은 자유롭게 변경할 수 있습니다.

액세스 태그는 추상화를 강제합니다

C++에서는 액세스 태그를 사용하여 클래스의 추상 인터페이스를 정의합니다. 클래스에는 0개 이상의 액세스 태그가 포함될 수 있습니다.

  • 공개 태그로 정의된 멤버는 프로그램의 모든 부분에 액세스할 수 있습니다. 유형의 데이터 추상 보기는 해당 공개 멤버에 의해 정의됩니다.

  • 비공개 태그를 사용하여 정의된 멤버는 클래스를 사용하여 코드에 액세스할 수 없습니다. 비공개 부분은 해당 유형을 사용하는 코드에서 구현 세부 정보를 숨깁니다.

접속 태그 빈도에는 제한이 없습니다. 각 액세스 태그는 뒤에 오는 구성원 정의의 액세스 수준을 지정합니다. 지정된 액세스 수준은 다음 액세스 태그가 발견되거나 클래스 본문의 닫는 닫는 괄호가 발견될 때까지 유효합니다.

데이터 추상화의 이점

데이터 추상화에는 두 가지 중요한 이점이 있습니다.

  • 클래스의 내부는 의도하지 않은 사용자 수준 오류로 인한 객체 상태 손상으로부터 보호됩니다.

  • 클래스 구현은 변화하는 요구 사항에 따라 또는 사용자 수준 코드를 변경할 필요가 없는 버그 보고서에 따라 시간이 지남에 따라 변경될 수 있습니다.

클래스의 비공개 부분에만 데이터 멤버를 정의하면 클래스 작성자가 마음대로 데이터를 변경할 수 있습니다. 구현이 변경되면 클래스의 코드만 확인하여 이 변경이 어떤 영향을 미치는지 확인하면 됩니다. 데이터가 공개된 경우 이전 표현의 데이터 멤버에 직접 액세스하는 모든 기능이 영향을 받을 수 있습니다.

데이터 추상화 인스턴스

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은 외부 인터페이스이므로 사용자가 클래스를 사용하려면 이를 알아야 합니다. Private 멤버 total는 사용자가 알 필요는 없지만 클래스가 제대로 작동하는 데 꼭 필요한 것입니다.

디자인 전략

추상화는 코드를 인터페이스와 구현으로 분리합니다. 따라서 구성 요소를 디자인할 때 인터페이스를 구현과 독립적으로 유지해야 합니다. 그러면 기본 구현이 변경되더라도 인터페이스는 변경되지 않고 그대로 유지됩니다.

이 경우 어떤 프로그램이 인터페이스를 사용하더라도 인터페이스는 영향을 받지 않으며 최신 구현만 다시 컴파일하면 됩니다.