정보은닉(Information Hiding)

정보은닉은 쓰여진 그대로 정보(Information)를 은닉(Hiding) 한다는 말이다.

그렇다면 C++에서 정보는 무엇이고 은닉은 어떻게 하는 것일까?

 

설명하기 쉽게 자동차 클래스를 통해 설명해 보겠다.

(이 글을 읽기전 클래스와 객체의 구분을 할 줄 안다는 가정하에 설명하겠다.)

 

-------------------------------

Class Car {

   char *Engine;

   char Gear; 

}

-------------------------------

 

자동차의 설계도(클래스)를 통해 마티즈 자동차를 만들었다고 생각해보자.

 

-------------------------------

Car Matiz;

-------------------------------

 

마티즈 자동차를 만든 후..

어느날 갑자기 자동차 설계도(클래스)의 엔진(변수)이라는 부품을 알고 있는 사람이

마티즈의 엔진에 V6엔진을 설정해 주면 어떻게 될까?

 

-------------------------------

Matiz.Engine = V; //V는 V6엔진

-------------------------------

 

마티즈 엔진은 V6을 달면서 더이상 마티즈 자동차가 아니게 된다.;;

또한 V6엔진이 작동은 되었어도 자동차가 이상하게 되어버린다.

 

이처럼 자동차 내부의 부품들을 알게되면 부품을 직접 제어할 수 있는데

이에 따른 문제점들이 있다.

직접 제어를 하게되면 잘못된 입력값 즉 엉뚱한 엔진을 넣어버릴 경우 이를 걸러줄

장치가 없다는 것이다.

 

이러한 매커니즘으로 탄생한 것이 정보은닉이다.

자동차의 부품을 C++에서 말한다면 클래스 내부에 선언되어있는 변수들을 말한다.

클래스에서 선언된 변수들이 내부에서만 사용되도록 만듬으로써

다른 외부의 조작으로부터 보호하고 잘못된 입력이 들어왔을 시에 제어해주는 역할이

바로 정보은닉의 이점이다.

 

이제 정보은닉을 하는 방법을 알아보도록 하자.

먼저 간단한 예제를 보자.

 

-------------------------------

#include <iostream>

 

class Car

{

private:

   char Engine;

   char Gear;

public:

   void SetEngine(char e) { Engine = e; }

   void SetGear(char g) { Gear = g; }

   char GetEngine() { return Engine; }

   char GetGear() { return Gear; }

}

 

int main()

{

   Car Matiz;

   Matiz.SetEngine(m);  //매개변수 m은 경차전용 M-TEC MPI 엔진으로 가정한다.

   Matiz.SetGear(d); // 매개변수 d는 기어 D 상태

   cout << GetEngine() << endl;

   cout << GetGear() << endl;

   return 0;

}

-------------------------------

 

아주 심플하게 정보은닉을 해보았다.

 

Main 함수에서 직접적으로 Car 클래스 변수들을

Matiz.Engine = V6; 처럼 직접 제어한 것이 아닌

Set...  ,  Get... 함수들을 통해 제어하였다.

 

Set.. Get.. 함수들을 Car 클래스 내부에서 선언하여 private으로 선언된 변수들을

제어함과 동시에 Set.. Get.. 함수들을 public으로 선언해서 외부에서 이 함수들을

통해 변수값을 넣도록 하고 있다.

 

이를 통해 얻을 수 있는 이점은

일단 Set.. 함수 이외에 다른 방법으로는 Car 클래스의 멤버변수들을 컨트롤 할 수 없다.

왜냐하면 변수들을 Car 클래스 내부에서만 사용하도록 private 선언을 하였기 때문에

외부에서 컨트롤 할 수 없다.

 

또한 Set.. 함수안에 올바른 값만들 받도록 정할 수도 있다.

예를 들면 Car 클래스의 SetEngine 함수에

 

-------------------------------

void SetEngine(char e) 

   if(e == m)  //m 은 경차전용 엔진이라 가정한다.

    Engine = e; 

}

-------------------------------

 

이와같이 추가해주면 경차전용엔진일 경우에만 Engine변수에 값을 넘기도록 설정할 수 있다.

따라서 V6엔진이라든지 다른 엔진을 설정하려고 할 경우를 막아준다.

 

 

 

요약하면

정보은닉이라 함은 말 그대로 정보를 은닉하는 것을 말하며

정보은닉을 통해 얻을 수 있는 이점은

클래스 내부 변수들을 외부에서 직접적으로 제어하지 못하게 막음으로써

항상 올바른 값만을 넘겨받아 작동할 수 있게 한다.

 

 

 

캡슐화(Encapsulation)

 

이번에는 캡슐화(Encapsulation)에 대해 설명하겠다.

 

객체지향언어라면 한번쯤 꼭 언급하고 넘어가는 것이 캡슐화이다.

 

캡슐화란 서로 관련되어 있는 변수와 함수들을 함께 묶는 것이라 할 수 있다.

 

앞서 사용한 자동차 예제를 들어보자.

자동차에는 엔진(Engine)과 기어(Gear)라는 부품이 존재한다.

그러나 엔진과 기어만 가지고 자동차라 부르기에는 역부족하다.

따라서 자동차라 부르기 위해서는 기어(Gear)를 통해

자동차가 전진과 후진을 할 수 있도록 하는 기능이 필요하다.

앞서 정보은닉에서 설명한 예제에 적용하도록 하자.

 

-------------------------------

#include <iostream>

 

class Car

{

 

private:

   char Engine;

   char Gear;

 

public:

   void SetEngine(char e) 

   { 

      if(e == 1)  //1 은 경차전용 엔진이라 가정한다.

       Engine = e; 

   }

   void SetGear(int g) { Gear = g; }

   char GetEngine() { return Engine; }

   char GetGear() { return Gear; }

   char Move()

   {

       if(Gear == 'd')

             전진하라.

       if(Gear == 'b')

             후진하라.

   }

}

 

int main()

{

   Car Matiz;

   Matiz.SetEngine(m);  //매개변수 1은 경차전용 M-TEC MPI 엔진으로 가정한다.

   Matiz.SetGear(d); // 매개변수 6은 6단기어라 가정한다.

   Matiz.Move();

   cout << GetEngine() << endl;

   cout << GetGear() << endl;

   return 0;

}

-------------------------------

 

자동차를 움직이는 기능을 갖는 함수 Move()를 Car 클래스 내부에서 선언해줌으로써

Car 클래스 내부에는 자동차와 관련된 기능들이 모이게 되었다.

 

이처럼 한 클래스 내부에 관련있는 함수와 변수들을 두는 것을 캡슐화 한다고 말한다.

캡슐화가 가져다 주는 이점은

예를 들어 위의 Car 클래스를 가지고 마티즈 자동차를 여러대 만들었다고 생각해보자.

그런데 만약 마티즈 자동차가 후진할 때 이상한 현상이 생겼다고 해보자.

이때 여러대 마티즈의 후진할 때 문제를 한번에 해결할 수 있는 방법은

Car 클래스 내부에 있는 Move()함수만을 확인해 보면 해결된다.

만약 자동차와 관련된 Move()함수가 다른 클래스에 있다고 하면

문제가 생겼을 시 Move()함수를 찾기위해 애를 써야 할 것이다.


+ Recent posts