[Effective C++] 22. 데이터 멤버가 선언될 곳은 private 영역임을 명시하자

C++/Effective C++

2020. 8. 29. 20:18

이번 항목은 코딩을 처음 배울 때 학원 선생이 늘 강조하던 캡슐화를 다루는 항목이다.

처음 객체지향에 손을 댔을 때 도통 get/set private/protected/public을 왜 써야하는지 알지 못했다.

애초에 혼자 만들다 보니 접근제한자는 그다지 쓸모가 없었고 get/set은 만들다가 지쳐서 안만든 기억이 있다.

 

거두절미하고 public 데이터 멤버를 사용하지 말아야 하는 이유에 대해 적어보겠다.

 

  • 문법적 일관성
  • 함수를 통한 정교한 제어
  • 캡슐화

먼저, 문법적 일관성에 대해 설명해 보겠다. 데이터 멤버가 모두 public이 아니라면 해당 데이터에 대한 접근 방법은 함수를 통한 방법 뿐이며, 그 클래스 멤버에 접근하고 싶을 때 괄호를 붙여야 하는지 말아야 하는지 고민할 필요 없이 함수를 통해서만 접근하면 될 것이다. 어떤 것은 함수로 어떤 것은 변수로 접근해야 한다면 쓸데없는 일로 시간낭비를 할 것이다.

 

두 번째 함수를 통한 정교한 제어는 값을 읽고 쓰는 함수가 있으면 접근 불가, 읽기 전용, 읽기 쓰기 접근을 직접 구현할 수 있다는 것이다. 이러한 세밀한 접근 제어는 어떤 식으로든 외부에 노출시키면 안되는 데이터 멤버들이 많기에 나름대로의 중요성을 가지고 있다.

 

마지막으로 캡슐화가 가장 중요한 이유가 되겠다. 데이터 멤버는 나중에 어떤 이유로서 대체 될수가 있다. 혹은 어떤 데이터 멤버가 의미하는 값의 계산식이 바뀌는 경우에도 캡슐화를 통해 내부의 코드만 바꿔주면 외부의 사용자는 그저 컴파일만 하면 그대로 사용할 수 있게 된다는 점이다!

 

이러한 특성들뿐만 아니라, 데이터 멤버를 함수 인터페이스 뒤에 감추게 되면 구현상의 융통성을 전부 누릴수 있게된다. 

ex)

  • 멤버 read/write 시 알림 메시지 기능
  • 클래스의 불변속성 검증
  • 사전조건/사후조건 검증
  • 스레딩 환경 동기화
캡슐화는 현재의 구현을 나중에 바꾸기로 결정할 수 있는 권한을 예약하는 셈이다.

 

다음으로, public/protected 데이터 멤버에 대해서도 알아보자.

어떤 클래스에 public 데이터 멤버가 있고, 이것을 제거한다고 가정해보자. 얼마나 많은 코드가 망가지겠는가?

파악조차 힘들만큼 엄청 많은 코드가 망가질 것이다. protected도 이와 거의 다를 바 없다. 오십보백보이다. 해당 클래스를 상속한 모든 클래스에 대해 영향을 미칠지어다.

 

결국 접근 수준은 private (캡슐화 제공) vs (public/protected) (캡슐화 없음) 이렇게 둘뿐이라고 생각하고 사용해야한다.

 

이것만은 잊지 말자!

  • 데이터 멤버는 private 멤버로 선언합시다. 이를 통해 클래스 제작자는 문법적으로 일관성 있는 데이터 접근통로를 제공할 수 있고, 필요에 따라서는 세밀한 접근 제어도 가능하며, 클래스의 불변속성을 강화할 수 있을 뿐 아니라, 내부 구현의 융통성도 발휘할 수 있습니다.
  • protected는 public보다 더 많이 '보호'받고 있는 것이 절대로 아닙니다.