항목 27에서 Pimpl 이디엄을 사용하여, 컴파일 타임 상호 의존성을 매우 줄였다. 하지만 Pimpl 을 어떻게 짜야만 더 좋고 안전하게 만들 수 있는지에 대해서는 무시하고 진행 했었다.

그런데.. 생뚱맞게 왜 항목이 "컴파일 방화벽" 이라는 말이 나왔지? 곰곰해 생각해 보면 Pimpl 이디엄은 그 컴파일러 입장에서 보면, 보이지 않는 벽같은 것이라 할 수도 있겠다. 음~

본론으로 들어와서, 어떻게 만드는 것이 가장 좋을까? 크게 몇가지 규칙을 적어 본다.

  1. 모든 private 데이터를 XImpl에 넣는다.(함수는 제외)
  2. 모든 private 멤버들을 XImpl에 넣는다.
  3. 모든 Private와 Protected 멤버들을 XImpl 에 넣는다.
  4. XImpl을 전체적으로 X가 가지고 있는 클래스로 만들고, X를 단지 간단한 포워딩 함수들로 이루어진 public 인터페이스만으로 작성한다.

각각의 장단점이 무엇이며, 어느 것을 선택 하겠는가?
XImpl은 X 개체로 되돌아가기 위한 포인터가 필요하는가?


분석

PImpl의 장점과 단점은 항목 27에서 설명 했었다. 이제 각 선택에 대해서 설명해 보자.

선택 1. (점수 : 6 / 10)
데이터 멤버들만 보이는 클래스들은 숨기게 되므로 좋은 시작이 될 수 있다. 하지만 더 좋은 방법이 있음을 선택2에서 설명 하겠다.

선택 2. (점수 : 10 / 10 )
클라이언트든 컴파일러든 헤더파일에 대해서 알 필요도 없고, 알아서도 안되므로, 이 방법만(각주 참조)을 허브셔터는 사용한다고 한다.[각주:1] 하지만 몇가지 주의점이 있으므로 주의점을 정리해 보자.

  1. private: 영역의 함수가 가상 함수라면 Pimpl에 넣을 수 없다.
  2. private: 영역의 함수가 재정의 되어질 것이라면 Pimple에 넣을 수 없다.
  3. Pimpl에서 자신을 담는 클래스를 호출 하고자 할때는 "후진 포인터"[각주:2]를 사용 해야 한다.
  4. Pimpl에서 private: 영역의 함수가 굳이 필요 없다면, 넣지 않는 것이 좋다.


요약 한다면 private: 영역 함수의 함수를 넣을 때, 4가지를 고려 해봐라 라는 것이다.

선택 3. (점수 : 0 / 10 )
protected 멤버로 설정했다는 것은 상속 관계에서 사용될 수 있다는 것을 의미하기 때문에, private:에 있는 Pimpl안에 protected를 넣는 다는 것은 그 의미가 없어 지므로, 절대 하지 말아야 한다.

선택 4. (점수 : 10 / 10)
후진 포인터를 피하는 이점이 있지만, 클래스가 파생 관계에 놓이게 될 때, 전혀 사용 할 수 없는 문제점을 가지고 있다. 즉 한정된 경우에는 편하다.

대답은 가끔 필요하다. 모체 클래스의 public: 영역의 함수들로 인하여 Pimpl 을 사용 되어져야 할 때, 접근 인터페이스를 제공해야 하기 때문이다.


총평

경우에 따라 달라지겠지만, 선택 2번으로 구현하고, private: 함수들에 대해서 애매할 때는 밖으로 빼 놓고 사용 되는게 더 편할 듯 싶다. private: 영역의 멤버 함수들에 대해서 사용 할 때는 좀 생각해 봐야 겠다. 그리고 "후진 포인터" 라... 아마도



  1. 이 방법만을 사용한다는 것은 그냥 그렇겠구나 싶은 것일 뿐이다. 실제로 그 상황에 따라서 다른 구현을 사용 한다. [본문으로]
  2. 일반적으로 Self_ 를 붙여 준다고 한다. 여기서의 후진 포인터는 Pimpl을 담는 클래스의 포인터를 뜻한다. [본문으로]
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 라이프코리아트위터 공유하기
  • shared
  • 카카오스토리 공유하기