Реализация предназначена только для того, чтобы позволить вам создавать элементы с помощью get_instance (). В идеале вы должны сделать свой конструктор копирования и оператор присваивания приватным.
Это не будет потокобезопасным. Вместо этого вы можете использовать следующее:
const boost::once_flag BOOST_ONCE_INIT_CONST = BOOST_ONCE_INIT;
struct AControl
{
boost::once_flag onceFlag;
shared_ptr<A> aInst;
void create( const B&b, int x )
{
aInst.reset( new A(b, x) );
}
AControl() : onceFlag( BOOST_ONCE_INIT_CONST )
{
}
A& get( const B&b, int x )
{
boost::call_once( onceFlag, bind( &AOnceControl::create, this, b, x ) );
return *aInst;
}
};
Изменить карту на
карта
Иметь мьютекс и использовать его таким образом:
AControl * ctrl;
{
mutex::scoped_lock lock(mtx);
ctrl = &cache[hash];
}
return ctrl->get(b,x);
В идеале только get_instance () будет статичным в вашем классе. Все остальное является частной реализацией и входит в модуль компиляции вашего класса, включая AControl.
Обратите внимание, что вы могли бы сделать это намного проще, просто заблокировав весь процесс поиска на карте и создания, но затем вы блокируете дольше, пока выполняете длительный процесс построения. Так как это реализует блокировку на уровне записи после того, как вы вставили элемент. Более поздний поток может найти элемент неинициализированным, но логика boost::once
обеспечит его создание ровно один раз.