Pointer to Implementation
Pimpl(Pointer to Implementation) Idiom이란 include가 필요한 유저 define 타입의 멤버변수들을 해당 멤버변수들을 포함한 구조체의 포인터로 대체하는 방법이다.
Synopsis
//in header Widget.h
#include <string>
#include <vector>
#include <Gadget.h>
class Widget{
public:
Widget();
...
private:
std::string name;
std::vector<double> data;
Gadget g1, g2, g3;
}
Pimpl Idiom을 사용하지 않는다면, 자주 보는 형태의 헤더파일일 것이다. 이런 형식의 헤더파일의 문제점은 헤더파일 내에서 다른 헤더파일을 include하고 있다는 것이다. #include를 사용하면 전처리기는 해당 헤더의 내용을 그대로 복사하여 집어넣는다. (최적화 하지 않는다고 가정하면) 그러면 Widget.h을 include 하는 모든 cpp 파일에 Widget.h가 include하는 모든 헤더를 포함하게 되므로 코드량이 매우 커질 것이다. 따라서 헤더에 다른 헤더를 include할수록 컴파일 시간이 늘어난다.
또 다른 문제는 re-complie 이다. string이나 vector와 같은 표준 라이브러리 함수는 내용이 바뀔일이 별로 없지만, Gadget같은 유저 정의 클래스의 헤더는 자주 바뀔 가능성이 높다. Gadget의 내용이 바뀐다면, Widget.h를 include하는 다른 모든 파일도 같이 재컴파일 될 수 밖에 없다. 이런 문제때문에 헤더는 다른 헤더를 가능하면 include하지 않는 것이 좋다. 그래서 사용하는 것이 Pimpl Idiom이다.
C++ 98에서 Pimpl Idiom
//in header Widget.h
class Widget{
public:
Widget();
~Widget();
...
private:
struct Impl; //Impl구조체 선언
Impl* pImpl; //다른 멤버들이 들어갈 구조체의 포인터
}
Favorite site
References
-
Modern_Effecitve_Cpp_item_22_-_Pimple_Idiom.pdf ↩