본문 바로가기
c++

[C++]정보은닉(information Hiding)

by goblin- 2023. 2. 18.

우리는 객체의 생성을 목적으로 클래스를 디자인한다. 좋은 클래스가 되기 위한 최소한의 조건에는 '정보은닉'과 '캡슐화'를 사용해야 한다.

 

다음 예를 통해 정보은닉이 필요성을 느끼고 좋은 클래스를 작성하려면 어떻게 해야 하는지 살펴보겠다.

(조건: x와 y의 범위는 0 이상 100 이하이고, 좌 상단 좌표가 [0,0] 우 하단의 좌표가 [100,100]이라고 가정하고 코드를 작성하자)

#include<iostream>
using namespace std;

class Point{
    public:
        int x;
        int y;
};

class Rectangle{
    public:
        Point upLeft;
        Point lowRight;
    
    public:
        void ShowRecInfo(){
            cout<<"좌 상단: "<<'['<<upLeft.x<<", ";
            cout<<upLeft.y<<']'<<endl;
            cout<<"우 하단: "<<'['<<lowRight.x<<", ";
            cout<<lowRight.y<<']'<<endl<<endl;
        }
};

int main(void){
    Point pos1={-2,4};
    Point pos2={5,9};
    Rectangle rec={pos2, pos1};
    rec.ShowRecInfo();
    return 0;
}
결과
좌 상단: [5, 9]
우 하단: [-2, 4]

위 코드의 문제점을 살펴보자. 점의 좌표는 0 이상 100 이하가 되어야 하는데, 그렇지 못한 Point 객체가 있다. 작사각형을 의미하는 Rectangle 객체의 좌 상단좌표 값이 우 하단 좌표 값보다 크다. 이러한 문제점들은 코드를 작성하면서 하는 사소한 실수로 볼 수 있다. 하지만 문제점은 실수에 대한 대책이 하나도 준비가 되어있지 않다는 점이다. 위의 코드처럼 프로그래머가 실수했을 경우 제한된 방법으로의 접근만 허용을 해서 잘못된 값이 저장되지 않도록 도와야 하고, 또 실수했을 때, 실수가 쉽게 발견되도록 해야 한다.

 

보완된 코드를 살펴 보겠다.

 

Point.h
#ifndef __POINT_H_
#define __POINT_H_

class Point{
    private:
        int x;
        int y;

    public:
        bool InitMembers(int xpos, int ypos);
        int GetX() const;
        int GetY() const;
        bool SetX(int xpos);
        bool SetY(int ypos);
};
#endif
Point.cpp
#include <iostream>
#include "Point.h"
using namespace std;

bool Point::InitMembers(int xpos, int ypos){
    if(xpos<0 || ypos<0){
        cout<<"벗어난 범위의 값 전달"<<endl;
        return false;
    }
    x=xpos;
    y=ypos;
    return true;
}
int Point::GetX() const {   //const 함수
    return x;
}
int Point::GetY() const{
    return y;
}
bool Point::SetX(int xpos){
    if(0>xpos || xpos>100){
        cout<<"벗어난 범위의 값 전달"<<endl;
        return false;
    }
    x=xpos;
    return true;
}
bool Point::SetY(int ypos){
   if(0>ypos || ypos>100){
        cout<<"벗어난 범위의 값 전달"<<endl;
        return false;
    }
    y=ypos;
    return true;
}

먼저 Point.h 코드를 살펴보면 멤버변수 x와 y를 private으로 선언해서 임의로 값이 저장되는 것을 막아놓았다. x와 y라는 정보를 은닉한 상황이다. 대신에 값의 저장 및 참조를 위한 함수를 추가로 정의하였다. 따라서 이 함수 내에서 멤버변수에 저장되는 값을 제한할 수 있게 되었다.

Point.cpp 코드를 살펴보면 함수 InitMembers, SetX, SetY는 0 이상 100 이하의 값이 전달되지 않으면, 에러 메시지를 출력하면서 값의 저장을 허용하지 않는 형태로 정의되었다.

멤버변수를 Private으로 선언하고, 해당 변수에 접근하는 함수를 별도로 정의해서, 안전한 형태로 멤버변수의 접근을 유도하는 것이 바로 '정보은닉'이며, 이는 좋은 클래스가 되기 위한 기본조건이 된다.

또한 위의 코드를 보면 GetX, GetY, SetX, SetY와 같이 정의된 함수들은 멤버변수를 private으로 선언하면서 클래스 외부에서의 멤버변수 접근을 목적으로 정의되는 함수들이다. 이들을 카리 켜 '액세스 함수(access function)'라고 한다.

'c++' 카테고리의 다른 글

[C++]캡슐화  (0) 2023.02.19
[C++] Const 함수  (0) 2023.02.18
[C++]객체지향 프로그래밍의 이해(메시지 전달)  (0) 2023.02.11
[C++]파일분할  (0) 2023.02.10
[C++]클래스와 객체  (0) 2023.02.09