객체지향 언어에서 클래스를 만들때 항상 나오는 말은 캡슐화(Encapsulation)다.
즉, 멤버변수는 private 접근 한정자로 외부의 직접적인 접근을 제한하고 클래스를 사용하는 외부에 인터페이스를 제공하여 직접 멤버변수를 접근하지 말자! 라는 의도이다.
사실 학부시절에는 캡슐화를 해야하는 당위성에 대해서 의문점이 많았고 굳이 getter,setter 인터페이스를 제공해서 멤버변수를 접근할 필요없이 객체의 값을 잘 사용만하면 문제 될 것이 없지 않나? 라는 생각을 했었다.
좀더 공부를 해보니 다음과 같은 이유로 캡슐화는 필수적인 작업이었다.
1) 문법적 일관성을 제공한다.
대부분의 개발자들이 멤버변수를 read하거나 write할 때 해당 데이터의 (만약 제공이 된다면)getter와 setter 함수를 사용한다.
즉, 멤버변수를 접근할때는 항상 함수(인터페이스)를 통해서 접근한다는 일관성을 제공한다.
2) Read만 가능한 멤버변수 Write만 가능한 멤버변수 둘다 가능 혹은 불가능한 멤버변수 구별해서 제공할 수 있다.
ex
class MyData {
private:
int readOnly;
int writeOnly;
int readWrite;
int noAccess;
public:
int getReadOnly() const {
return readOnly;
}
void setWriteOnly(int data) {
this->writeOnly = data;
}
int getReadWrite() const {
return readWrite;
}
void setReadWrite(int data) {
this->readWrite = data;
}
};
3) 구현상의 융통성 증가
객체를 접근하기 전 어떤 일들(precondition, postcondition, 특정이벤트등) 을 getter setter함수에서 구현할 수 있다. 이러한 점은 코드 중복을 제거해주기도 한다.
예를들어 readOnly 멤버변수를 get하기전에 항상 precondition 이 존재한다고 하면 아래와 같이 구현해주면 된다.
int getReadOnly() const {
preconditionFunc();
return readOnly;
}
4) 유지보수 용이
클래스의 멤버변수와 멤버함수를 공개(public)하는 것은 다른말로 바꾸기 수정하기 쉽지않다 라는 의미이다.
즉, 클래스에서 public으로 제공되는 함수나 변수의 수정이 생기게 되는 경우 해당 클래스를 사용하는 외부의 코드까지 모두 수정이 들어가게 된다.
예를들어 public 멤버변수의 이름이 바뀐다거나 public 멤버함수의 리턴타입 매개변수의 수정이 발생했을때를 상상해보면 이를 사용하는 다른 코드들도 함께 수정및 재컴파일이 필요하다.
만약 구현한 클래스가 라이브러리로 제공된다면 해당 라이브러리를 사용하는 모든 프로젝트를 수정하고 다시 컴파일 해야한다.
그래서 클래스를 최대한 캡슐화 했을때의 장점은 외부에 공개되지 않는(private) 멤버함수, 멤버변수의 수정이 발생해도 외부에서 사용하는 코드의 수정은 필요하지 않고 재컴파일의 가능성을 줄일 수 있다.
'C and C++' 카테고리의 다른 글
[C++] pImpl(pointer to implementation)를 이용해서 인터페이스와 구현을 분리하기 (0) | 2018.08.05 |
---|---|
[C++] C++ 스타일의 캐스트 (0) | 2018.07.25 |
[C++] 객체의 값을 전달할때 복사 비용을 줄이는 방법 "상수객체 참조자" (0) | 2018.07.10 |
[C++] RAII스타일로 동작하는 lock_guard (0) | 2018.06.25 |
[C++] 자원관리 Smart Pointer (shared_ptr) (0) | 2018.06.17 |