http://www.gotw.ca/gotw/028.htm
Pimpl Idiom[http://mkseo.pe.kr/blog/?p=841, http://www.gotw.ca/gotw/024.htm]의 단점은 1) heap 메모리 할당과 해제, 2) 포인터를 사용한 호출입니다.
그 중, 메모리 할당과 해제를 해결하기 위한 첫번째 시도:
// file y.h class Y { /*...*/ static const size_t sizeofx = /*some value*/; char x_[sizeofx]; }; // file y.cpp #include "x.h" // Pimpl Implementation class or struct Y::Y() { assert( sizeofx >= sizeof(X) ); new (&x_[0]) X; } Y::~Y() { (reinterpret_cast<X*>(&x_[0]))->~X(); }
그러나 이 방법은 char x_[sizeofx] 가 byte align을 안해준다는 문제, sizeofx 값을 사전에 알 수 없다는 문제가 있습니다. /* some value */ 자리에 sizeof(X)라고 쓰면 안되나? 라고 생각할 수 있지만, 그렇게 하려면 y.h 에서 #include “x.h”를 해서 X의 정의가 complete하게 만들어주어야합니다.
Herb Sutter가 제안한 방법은 fixed allocator를 정의하고, 그걸 상속받은 X를 만들란 것입니다.
struct FastPimpl { void* operator new( size_t s ) { return FixedAllocator::Instance()->Allocate(s); } void operator delete( void* p ) { FixedAllocator::Instance()->Deallocate(p); } }; struct X: FastPimpl { ... };
이러면 new와 delete의 오버헤드 문제가 해결되겠죠.