[C++] 캡슐화

dd_ddong·2022년 7월 15일
0

c++

목록 보기
16/38

캡슐화

캡슐화란 관련있는 모든 것을 클래스 안에 묶어두는 것이다.

캡슐화 안한 예

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 ColdPatient
{
public:
	void TakeSinivelCap(const SinivelCap& cap) const { cap.Take(); }
	void TakeSneezeCap(const SneezeCap& cap) const { cap.Take(); }
	void TakeSnuffleCap(const SnuffleCap& cap) const { cap.Take(); }
};

위와 같은 class 들이 있다면 ColdPatient가 약을 먹는다는 기능을 할려면

int main() {
	SinivelCap scap;
	SneezeCap zcap;
	SnuffleCap ncap;

	ColdPatient sufferer;
	sufferer.TakeSinivelCap(scap);
	sufferer.TakeSneezeCap(zcap);
	sufferer.TakeSnuffleCap(ncap);
}

위와 같이 함수호출을 해야 한다.
여기서 문제점은

  1. TakeCap 함수들의 호출순서가 결과에 영향을 미친다면 오류의 가능성이 높아진다.
  2. Cap 시리즈 함수가 변경된다면 ColdPatient 객체도 바꿔야하는 가능성이 생긴다.

캡슐화 적용

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 CONTA600
{
private:
	SinivelCap scap;
	SneezeCap zcap;
	SnuffleCap ncap;
public:
	void Take(){
   	scap.Take();
       zcap.Take();
       ncap.Take();
   }
}

class ColdPatient
{
public:
	void TakeCONTA600(const CONTA600 &cap) const {cap.Take();}
};

위와 같이 CONTA600으로 약을 먹는다라는 기능을 하나의 Take함수로 캡슐화를 한다면

int main() {
	CONTA600 cap;
    ColdPatient sufferer;
    sufferer.TakeCONTA600(cap);
}

main함수에서 suffer객체는 TakeCONTA600 함수호출만 한다면 기능을 수행할 수 있다.

여기서 캡슐화의 이점은

  1. ColdPatient객체는 CONTA가 Take함수가 있다는 정보말고는 몰라도 된다.
  2. 약을 먹는다는 기능을 사용하고 싶다면 CONTA의 Take함수만 이용하면 된다.
  3. 만약 약을 먹는다는 기능의 구현이 변경되더라도 Take함수만 변경하면 된다.

문제 4-2

class Point
{
private:
	int xpos, ypos;
public:
	void Init(int x, int y)
	{
		xpos = x;
		ypos = y;
	}
	void ShowPointInfo() const
	{
		cout << "[" << xpos << "," << ypos << "]" << endl;
	}

};

class Circle
{
private:
	Point center;
	int radius;
public:
	int GetRadius() const {
		return radius;
	}
	void Init(int x, int y, int radius) {
		this->radius = radius;
		center.Init(x, y);
	}
	void ShowCenter() {
		center.ShowPointInfo();
	}
};

class Ring
{
private:
	Circle circle1;
	Circle circle2;
public:
	void Init(int inx, int iny, int incen, int outx, int outy, int outcen)
	{
		circle1.Init(inx, iny, incen);
		circle2.Init(outx, outy, outcen);
	}
	void ShowRingInfo() {
		cout << "Inner Circle Info..." << endl << "radius : " << circle1.GetRadius()<< endl;
		circle1.ShowCenter();
		cout << "Outer Circle Info..." << endl << "radius : " << circle2.GetRadius() << endl;
		circle2.ShowCenter();
	}
};
int main() {
	Ring ring;
	ring.Init(1, 1, 4, 2, 2, 9);
	ring.ShowRingInfo();

}

보안점

Ring의 ShowRingInfo에서 GetRadius 호출 없이 ShowCircleInfo만 호출하면 되도록 만드는게 좋다. circle이 ShowCircleInfo를 구현한다는 것만 알아도 되기 때문

0개의 댓글