c++에서 사용하는 class는 public
, private
, protected
이렇게 세가지의 접근지정자로 구분돼서 사용됩니다.
왜 굳이 모두 외부에서 접근할 수 있게 만들지 않고 이렇게 구분지어서 나눠놓은 걸까요??
그 이유는 사용자가 굳이 알 필요가 없는 내용을 숨겨서
필요한 부분에만 집중
할 수 있도록 만들어주기 때문입니다.
간단하게 말 하면 우리가 어떤 전자제품을 쓸 때 사용하는 방법만 알면 되지 그 안에 내부 회로가 어떤 식으로 구성되어있는지는 알 필요가 없죠.
이런 것과 같다고 생각하시면 될 것 같습니다.
이렇게 캡슐화는 객체의 내부 데이터를 private
으로 처리함으로써 필요없는 내용을 가리고 그 내부 데이터의 접근과 변경을 처리할 수 있는 로직 한 곳에
묶놓음으로써 프로그래머의 실수를 줄이고, 이식성을 높이며 코드의 유지보수를 용이하게 만들어주는 방식입니다.
그러면 캡슐화를 함으로 인해서 얻을 수 있는 부분은 어떤 부분이 있을까요?
만약 우리가 어떤 물품 가격을 10% 할인된 금액을 구해야 할 때 이렇 게 처리한다고 해 봅시다.
void foo(Goods goods)
{
double discounted_price = goods.getPrice() * 0.9;
var(discounted_price);
}
할인된 가격인 discounted_price
를 다른 함수 var
로 넘겨서 사용한다고 해 봅시다.
이런 식으로 한 번 사용하는건 괜찮습니다. 하지만 이 수가 엄청나게 많아진다면?
뿐만 아니라 코드를 작성하는 사람이 달라져서 이렇게 할인하는 코드를 아래처럼 다른 방식으로 짠다면?
void foo(Goods goods)
{
double discounted_price = goods.getPrice() - goods.getPrice() * 0.1;
var(discounted_price);
}
만약 이 상태에서 할인율이 20%로 바뀐다면...?
안 그래도 이 코드가 사용된 곳을 찾아서 바꾸고 바꿔야하는데 다른 부분까지 존재한다면 문제가 많아지겠죠.
이러한 이유로 우리가 내부 로직을 밖으로 꺼내지 않고 사용하고 외부에서 사용할때는 객체에게 요청
하는 방식으로 사용해야 합니다.
만약 내부 데이터가 아무데서나 접근이 가능하고 변경이 가능하다고 생각을 해 봅시다.
그렇게 된다면 관리하기도 어렵고 실수를 하기가 쉽습니다.
class MyString
{
private:
char* m_string;
int m_length;
};
다음과 같은 클래스가 있을 때 m_length
는 항상 m_string
의 길이여야 합니다.
외부에서 마음대로 바꿀 수 있게 되어있다면 큰 문제가 발생할수도 있습니다.
참고
[ c++ ] namespace
[ c++ ] 클래스, 생성자, 소멸자, 이니셜라이저, this포인터
[ c++ ] c++에서의 const와 static
[ c++ ] 참조자(reference)
[ c++ ] new와 delete
[ c++ ] 함수 오버로딩
[ c++ ] 파일 입출력 (ifstream, ofstream)
[ c++ ] 함수포인터, 멤버 함수포인터
[ c++ ]연산자 오버로딩
[ c++ ] 캡슐화란?
[ c++ ] 상속과 다형성에 대해 알아보자