메서드 구현 숨기기
- 모든 멤버 변수를 노출하지 않는 것과 함께 public으로 선언할 필요가 없는 모든 메서드를 감추는 것도 중요
정보은닉 사용한 프로그램이 그렇지 않은 것 보다 4배 쉬움
* 클래스는 그것이 어떻게 구현될지를 정의하는 것 아니라 무엇을 할 것인지 정의
* 절대로 비상수 포인터나 참조를 private 데이터 멤버로 리턴하지 않는다 이것은 캡슐화를 어기는 행위
* URLDownloader 클래스의 경우 생성자와 DownloadToFile() 메서드를 제외하고 모두 private으로 선언
- 그 다음은 메서드를 제대로 구현
- 이제 코드를 변경해야 한다 해도 클라이언트에게 미칠 영향을 걱정하지 않고 자유롭게 코드를 수정
- 지금까지는 컴파일러의 관점에서 API의 상세한 구현 코드가 보이지 않도록 노력했다
- 하지만 사람들은 여전히 헤더 파일을 볼 수 있고 클래스의 내부를 들여다 볼 수 있다
- 클라이언트는 API와 함께 컴파일 되어야 하기 때문에 API의 헤더 뿐만 아니라 API 클래스의 private 멤버 변수가 요구하는 #include에 명시된 명시된 헤더 파일도 같이 배포
- 비록 private 멤버 변수가 public 인터페이스와 관련이 없다 해도 상황은 달라지지 않는다
- 예를 들면 URLDownloader 클래스 헤더는 플랫폼에 정속된 모든 소켓의 헤더를 #include로 추가
- 이는 불행하게도 C++ 언어가 주는 제약사항
- 클래스를 구현하기 위해 구현에 필요한 모든 public, protected, private 멤버들을 선언
이상적으로 보자변 앞서 구현한 URLDownloader 클래스 헤더는 다음과 같음
#include <string>
class URLDownloader
{
public:
URLDownloader();
bool DownloadToFile(const std::string& url, const std::string& localfile);
};
- 모든 private 멤버 변수는 .cpp 파일에 선언하면 된다
- 그러나 C++에서는 그럴 수 없다 (이유는 모든 컴파일 시 모든 객체의 크기를 알아야 하기 때문)
- 그럼에도 불구하고 private 멤버를 헤더 파일에 선언하지 않을 수 있다
- 바로 Pimple 관용법
- 이 기술은 .cpp 파일에 있는 구조체나 클래스 코드 안에 private 멤버 변수를 격리
- .h 파일은 그저 이 구현 클래스의 불투명 포인터를 담고 있을 뿐
- 헤더 파일에서 구체적인 내용을 완전히 제거할 수 있도록 API 개발시에는 Pimple 관용법의 사용을 적극 권장
- 만약 이 방법을 사용하지 않기로 결정했다면 최소한 헤더 파일에 있는 불필요한 private 멤버 변수를 .cpp 파일로 옮기고 정적 함수로 변환하는 노력이라도 해야 한다
- 많은 개발자들은 당연히 클래스가 private 멤버들을 자주 사용하기 때문에 클래스 선언에 이 멤버들을 포함해야 된다고 생각하지만, 그렇게 하면 필요 이상으로 구체적인 내용을 쉽게 노출
* 내부적으로 사용하는 기능을 private 메서드로 헤더 파일에 선언하기 보다는 .cpp 파일에서 정적 함수로 선언