개발/C, C++

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

huiyu 2018. 12. 15. 16:33

- 정보은닉

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
 
using namespace std;
 
class Point
{
  public:
    int x; // x 좌표 범위는 0이상 100이하
    int y; // y 좌표 범위는 0이상 100이하
};
 
class Rectangle
{
  public:
    Point upLoeft;
    Point lowRight;
 
 
  public:
    void ShowRecInfo()
    {
      cout<<"좌 상단 : "<<'['<<upLeft.x<<",";
      cout<<upLeft.y<<']'<<endl;
      cout<<"우 하단: "<<'['<<lowRight.x<<", ";
      cout<<lolwRight.y<<']'<<endl<<endl;
    }
};
 
int main(void)
{
  Point pos1 = {-24};
  Point pos2 = {59};
  Rectangle rec = {pos2, pos2};
  rec.ShowRecInfo();
 
  return 0;
}
cs

- Rectangle객체 안에는 두 개의 Point객체가 포함되어 있다.
- 미리 선언된 Point의 pos1, pos2는 Rectangle의 좌상단과 우하단의 값으로 저장된다.


*위 코드의 문제점

 - 점의 좌표는 0이상 100이하가 되어야 하는데, 그렇지 못한 Point객체 존재
 - 직사각형인 Rectangle 객체의 좌상단 좌표값이 우하단 좌표값보다 크다.

-> 예제 코드는 위의 문제점이 생길 수 있는 가능성이 있다. 그러나 이러한 대책에 대한 준비가 되어있지 않다.
 **제한된 방법으로의 접근만 허용을 해서 잘못된 값이 저장되지 않도록 도와야 하고, 실수 했을 경우, 실수가 쉽게 발견되도록 해야된다.


*해결방법

 [Point.h]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#ifndef __POINT_H_
#define __POINT_H_
 
class Point
{
  private:
    int x; // x 좌표 범위는 0이상 100이하
    int y; // y 좌표 ㅁ위는 0이상 100이하
 
  public:
    bool InitMembers(int xpos, int ypos);
    int GetX() const;
    int GetY() const;
    bool SetX(int xpos);
    bool SetY(int ypos);
};
#endif
 
cs

-> 멤버변수 x와 y를 private으로 선언해서 임의로 값이 저장되는 것을 막는다. 즉 x와y 정보를 은닉한 것이다.
-> 대신 값의 저장 및 참조를 위한 함수를 추가로 정의, 이 함수를 통에 멤버변수에 저장되는 값을 제한할 수 있다.

[Point.cpp]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#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
{
  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;
}
cs

-> 멤버변수에 값을 저장하는 함수 InitMembers, SetX, SetY는 0이상 100이하의 값이 전달되지 않으면 에러를 출력하며 값이 저장안되도록 정의,
  따라서 잘못된 값을 저장할 수 없을 뿐만 아니라 에러 메시지도 확인 가능하다.

-> 액세스 함수(Access function) 정의
 : 멤버변수를 private으로 선언하면서 클래스 외부에서의 멤버변수 접근을 목정으로 정의 되는 함수 ->SetXXX(), GetXXX()

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


***const 함수

    int GetX() const;
    int GetY() const;

 - 의미 : 이 함수 내에서는 멤버변수에 저장된 값을 변경하지 않겠다.

 -> const선언이 추가된 멤버함수 내에서 멤버변수의 값을 변경하는 코드가 삽입되면, 컴파일 에러가 발생한다.
  이렇게 함수를 const로 선언하면, 실수로 자신의 의도와 다르게 멤버변수의 값을 변경했을 때, 컴파일 에러를 통해서 이를 확인할 수 있다.


 - const함수 내에서는 const가 아닌 함수의 호출이 제한된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class SimpleClass
{
private:
  int num;
 
public:
  void InitNum(int n)
  {
    num = n;
  }
 
  int GetNm() // const가 추가되어야 아래 컴파일 에러가 사라진다.
  {
    return num;
  }
 
  void ShowNum() const
  {
    cout<<GetNum()<<endl//컴파일 에러발생
  }
 
}
cs

 -> const로 선언되지 않은 함수는 아무리 멤버변수에 저장된 값을 변경하지 않더라도, 변경할 수 있는 능력을 지닌 함수이다.
  const함수는 이러한 변경이 가능한 함수의 호출을 아예 허용하지 않는 것이다.


[참고]
윤성우 열혈 C++ 프로그래밍 04-1 정보은닉(Information Hiding)

728x90
반응형

'개발 > C, C++' 카테고리의 다른 글

[C++] this 포인터  (0) 2018.12.16
[C++] 생성자(Constructor)와 소멸자(Destructor)  (0) 2018.12.16
[C++] 클래스(Class)와 객체(Object)  (0) 2018.12.15
[C++] C++에서의 구조체  (0) 2018.12.15
[C++] 참조자(Reference)와 함수  (0) 2018.12.09