728x90
정보 은닉 (Information)
: 클래스의 멤버변수를 private로 선언, 해당 변수에 접근하는 함수를 별도로 정의해,
안전한 형태로 멤버 변수의 접근을 유도한다.
Point 클래스의 정보은닉
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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); }; | cs |
8 행 : 벗어난 범위의 값 저장을 막는 초기화 함수
9-12 행 : 정보 은닉으로 인해 추가되는 접근(access) 함수들
get은 값을 반환, set은 값을 저장하는 함수로 엑세스 함수를 추가하는 것이 일반적
1 2 3 4 5 6 7 8 9 10 11 | bool Point::SetX(int xpos) { if(0>xpos || xpos>100) { cout<<"벗어난 범위의 값 전달"<<endl; return false; } x=xpos; return true; } | cs |
Rectangle 클래스의 정보 은닉
1 2 3 4 5 6 7 8 9 10 | class Rectangle { private: Point upLeft; Point lowRight; public: bool InitMembers(const Point &ul, const Point &lr); void ShowRecInfo() const; }; | cs |
1 2 3 4 5 6 7 8 9 10 11 | bool Rectangle::InitMembers(const Point &ul, const Point &lr) { if(ul.GetX()>lr.GetX() || ul.GetY()>lr.GetY()) { cout<<"잘못된 위치정보 전달"<<endl; return false; } upLeft=ul; lowRight=lr; return true; } | cs |
3-7 행 : 좌 상단과 우 하단이 바뀌는 것을 막는다. (우 하단의 좌표값이 더 작은것은 말이 안되므로)
const 함수
멤버 함수의 const 선언
: 동일 클래스에 선언된 멤버 변수의 값을 변경하지 못하도록 선언
1 2 3 4 | // const함수내에서는 동일 클래스에 선언된 멤버 변수의 값을 변경하지 못함 int GetX() const; int GetY() const; void ShowRecInfo() const; | cs |
다음과 같은 경우는 주의!
const 함수내에서는 const 선언되지 않은 함수를 호출하지 못함
다음과 같은 함수 호출은 컴파일 에러를 일으킨다.
GetNum함수가 값을 변경할 수 있는 가능성이 내포되어 있기 때문이며 이를 해결하려면 GetNum함수에 const선언을 추가해야 한다.
1 2 3 4 5 6 7 8 9 | // 멤버 함수 GetNum, ShowNum int GetNum() { return num; } void ShowNum() const { cout<<GetNum()<<endl; // 컴파일 에러 } | cs |
const로 상수화된 객체를 대상으로도 const 멤버함수만 호출 가능. 역시 이를 해결하려면 GetNum함수에 const선언을 추가해야 함.
1 2 3 4 5 | // GetNum이 const 선언되지 않았다고 가정 void InitNum(const EasyClass &easy) { num=easy.GetNum(); // 컴파일 에러 } | cs |
캡슐화 (Encapsulation)
: 관련있는 모든 것들을 하나의 클래스 안에 묶는 것
아래의 class들은 감기알약에 대해 나름의 캡슐화를 한 것이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | class SinivelCap // 콧물 처치용 캡슐 { public: void Take() const {cout<<"콧물이 싹~ 납니다."<<endl;} }; class SneezeCap // 재채기 처치용 캡슐 { public: void Take() const {cout<<"재채기가 멎습니다."<<endl;} }; class SnuffleCap // 코막힘 처치용 캡슐 { public: void Take() const {cout<<"코가 뻥 뚫립니다."<<endl;} }; | cs |
하지만 다음과 같은 조건이라면 이는 캡슐화가 제대로 되지 않은 것이다.
1. 코 감기가 하나의 증상이 아닌 여러 증상을 동반한다.
2. 복용에 대한 순서나 방법이 정해져있다.
따라서 이 경우 제대로 된 캡슐화가 필요하며, 다음과 같이 관련 클래스를 하나로 묶을 필요성이 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class CONTAC600 { private: SinivelCap sin; SneezeCap sne; SnuffleCap snu; public: void Take() const { sin.Take(); sne.Take(); snu.Take(); } }; | cs |
4-6행 : 코 감기와 관련된 캡슐을 하나로 묶음
9행 : 약의 복용 순서를 정의
1 2 3 4 5 | class ColdPatient { public: void TakeCONTAC600(const CONTAC600 &cap) const { cap.Take(); } }; | cs |
위의 ColdPatient 클래스는 CONTAC600 클래스의 내용이 수정 및 추가되라도 바뀔 필요가 없다.
캡슐화 관련 예제
#include <iostream>
using namespace std;
class SinivelCap // 콧물 처치용 캡슐
{
public:
void Take() const { cout << "콧물이 싹~ 납니다." << endl; }
};
class SneezeCap // 재채기 처치용 캡슐
{
public:
void Take() const { cout << "재채기가 멎습니다." << endl; }
};
class SnuffleCap // 코막힘 처치용 캡슐
{
public:
void Take() const { cout << "코가 뻥 뚫립니다." << endl; }
};
class CONTAC600
{
private:
SinivelCap sin;
SneezeCap sne;
SnuffleCap snu;
public:
void Take() const
{
sin.Take();
sne.Take();
snu.Take();
}
};
class ColdPatient
{
public:
void TakeCONTAC600(const CONTAC600 &cap) const
{
cap.Take();
}
};
int main(void)
{
CONTAC600 cap;
ColdPatient sufferer;
sufferer.TakeCONTAC600(cap);
return 0;
}
|
해당 함수가 속한 객체의 멤버를 변경할 수 없도록 const 함수
캡슐화의 이점
: A 클래스가 잘 캡슐화 되었다면, 이 A클래스가 변경되더라도,
A와 연관된 다른 클래스는 변경될 필요가 없거나 변경 범위가 최소화된다는 것이다.
'Study > C++' 카테고리의 다른 글
객체 배열과 this포인터 (0) | 2016.09.27 |
---|---|
생성자와 소멸자, 클래스 (0) | 2016.09.26 |
CPP-Object Oriented Programming (객체지향 프로그래밍) (0) | 2016.09.23 |
c++ Class (0) | 2016.09.22 |
c++ 기초3 (0) | 2016.09.21 |