The "Fast Pimpl" Idiom

来源:互联网 发布:网络推广软件哪个好 编辑:程序博客网 时间:2024/05/04 08:17
// file y.hclass X;class Y{/*...*/X* px_;};// file y.cpp#include "x.h"Y::Y() : px_( new X ) {}Y::~Y() { delete px_; px_ = 0; }// This nicely hides X, but it turns out that Y is used very widely and the dynamic allocation // overhead is degrading performance.// Attempt #3 // file y.hclass Y{/*...*/static const size_t sizeofx = /*some value*/;char x_[sizeofx];};// file y.cpp#include "x.h"Y::Y(){assert( sizeofx >= sizeof(X) );new (&x_[0]) X;}Y::~Y(){(reinterpret_cast<X*>(&x_[0]))->~X();}// file x.h class X{/*...*/struct XImpl;XImpl* pimpl_;};// file x.cpp#include "x.h"struct X::XImpl{/*...private stuff here...*/static void* operator new( size_t )   { /*...*/ }static void  operator delete( void* ) { /*...*/ }};X::X() : pimpl_( new XImpl ) {}X::~X() { delete pimpl_; pimpl_ = 0; }template<size_t S> class FixedAllocator{public:void* Allocate( /*requested size is always S*/ );void  Deallocate( void* );private:/*...implemented using statics?...*/};class FixedAllocator {public:  static FixedAllocator& Instance();  void* Allocate( size_t );  void  Deallocate( void* );private:  /*...singleton implementation, typically       with easier-to-manage statics than       the templated alternative above...*/};struct FastArenaObject {static void* operator new( size_t s ){return FixedAllocator::Instance()->Allocate(s);}static void operator delete( void* p ){FixedAllocator::Instance()->Deallocate(p);}};//  Want this one to be a Fast Pimpl? //  Easy, then just inherit...struct X::XImpl : FastArenaObject{/*...private stuff here...*/};//  have some problem, i don't see it. 30