캡슐화란 관련있는 모든 것을 클래스 안에 묶어두는 것이다.
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);
}
위와 같이 함수호출을 해야 한다.
여기서 문제점은
- TakeCap 함수들의 호출순서가 결과에 영향을 미친다면 오류의 가능성이 높아진다.
 - 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 함수호출만 한다면 기능을 수행할 수 있다.
여기서 캡슐화의 이점은
- ColdPatient객체는 CONTA가 Take함수가 있다는 정보말고는 몰라도 된다.
 - 약을 먹는다는 기능을 사용하고 싶다면 CONTA의 Take함수만 이용하면 된다.
 - 만약 약을 먹는다는 기능의 구현이 변경되더라도 Take함수만 변경하면 된다.
 
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를 구현한다는 것만 알아도 되기 때문