배경
이 내용은 모듈화에 대한 생각으로부터 시작합니다. 저는 개인적으로 어떤 코드 조각이 큼지막한 것을 꽤 싫어합니다. 특히 헤더가 지저분한 것은 딱 질색입니다. 일반적으로 헤더는 사용자가 쓰기에 일목요연하고 정리된 모습을 보여줘야 한다고 생각합니다. 그러기 위해서는 필요에 의한 것(객체 혹은 함수)들과 사용자에게 제공하는 것들을 구분할 필요가 있습니다. 이에 관하여 흥미로운 내용을 [The C++ Programming Language]에서 발견하였고 그 내용을 간단히 정리하고자 합니다.
사용자와 구현자
일반적으로 어떠한 코드 조각(Code segmant)를 구현하였을 때, 그 코드 조각이 필요한 사람들은 대부분 사용자와 구현자 로 구분할 수 있습니다. 구현자는 코드 조각의 세세한 내용까지를 필요로 하는 반면, 사용자는 그 모듈을 어떻게든 사용할 수 있는 방법만 알면 됩니다. 그래서 나온 내용이 설계(Interface)와 구현(Implementation)의 분리이지요. 이제부터 설명하고자 하는 내용은 설계와 구현의 분리에 대한 C++에서의 이용 방법입니다.
클래스의 은닉화(Encapulation)
객체지향 언어의 클래스에서는 설계와 구현의 분리를 위해 public과 private, protected라는 접근 권한을 제공합니다. 이 내용은 클래스의 사용자로 하여금 어디까지가 이용 가능한 것인지를 명시해줍니다. 하지만 더욱 좋은 은닉화는 사용자에게 정보조차 제공하지 않는 것이라고 여겨집니다. 즉, 너는 이러이러한 내용만 알고 있었도 이 내용을 쓰는 데에 하등의 문제가 없다고 알리는 것이죠. 이것을 위해서 필요한 것이 함수의 중복 선언입니다.
함수의 중복 선언
C++에서 정의는 한 번밖에 가능하지 않지만 선언은 얼마든지 할 수 있습니다. 이를 이용하면 사용자가 필요로 하는 정도에 따라 필요한 내용만을 전달할 수 있습니다. 즉, 같은 내용에 대해 해당하는 함수의 내용만을 주는 것입니다. 일례를 들면 다음과 같습니다.
file: adder.h struct Complex { float r, i; }; void Expr( ostream &os );
file: adder_impl.h #include "adder.h" struct Complex; void Expr( ostream &os ); const Complex Generate();
사용자에게 제공하는 헤더는 adder.h고 구현자들이 사용할 헤더는 adder_impl.h 입니다. 구현은 adder_impl.cpp가 adder_impl.h를 포함(include)하여 구현하면 됩니다.
여러 계층에게 다른 종류의 헤더 주기
사실 굳이 중복 선언이 따로 필요한 것은 아닙니다. adder_impl.h에는 void Expr()이 굳이 있을 필요는 없습니다. 다만 adder.h 말고도 adder_advance.h 등과 같이 다른 필요를 가진 계층이 나타났다면 그에 맞는 함수들만 쭉 적어주면 좋습니다. 단, 주의점은 구현부에서는 설계만 되어있는 모든 파일을 포함해주어야만 합니다.
결론
별 내용은 아닙니다. 여기서 이용한 것은 단순히 함수가 중복 선언이 가능하다는 사실밖에는 없습니다. 하지만 헤더 파일과 소스 파일에 그 파일 이름에 맞는 클래스 하나만 존재하는 프로그래밍만 있지 않다는 사실을 다시 한 번 환기할 수 있는 기회가 되었으면 좋겠습니다.
'프로그래밍 > C++' 카테고리의 다른 글
생성자 제작 시 제한사항 (4) | 2007.02.07 |
---|---|
한 스트림을 다른 스트림으로 연결하기 (0) | 2007.02.07 |
[C++] Insertion Sequance( std::vector, ... ) (4) | 2006.04.19 |
[C++] 선언 없이 단 한 번만 실행되기 (6) | 2006.04.03 |
단일체 (8) | 2006.03.08 |