Это становится распространенным шаблоном в моем коде, когда мне нужно управлять объектом, который должен быть некопируемым, потому что либо A. это «тяжелый», либо B. это ресурс операционной системы, такой как критический раздел :
class Resource;
class Implementation : public boost::noncopyable
{
friend class Resource;
HANDLE someData;
Implementation(HANDLE input) : someData(input) {};
void SomeMethodThatActsOnHandle() {
//Do stuff
};
public:
~Implementation() { FreeHandle(someData) };
};
class Resource
{
boost::shared_ptr<Implementation> impl;
public:
Resource(int argA) explicit {
HANDLE handle =
SomeLegacyCApiThatMakesSomething(argA);
if (handle == INVALID_HANDLE_VALUE)
throw SomeTypeOfException();
impl.reset(new Implementation(handle));
};
void SomeMethodThatActsOnTheResource() {
impl->SomeMethodThatActsOnTheHandle();
};
};
Таким образом, shared_ptr заботится о головной боли при подсчете ссылок, позволяя копировать Resource
, даже если основной дескриптор должен быть закрыт только после уничтожения всех ссылок на него.
Тем не менее, похоже, что мы могли бы сэкономить накладные расходы на распределение счетчиков ссылок shared_ptr и такие отдельно, если бы мы могли как-то переместить эти данные в Implementation
, как это делают навязчивые контейнеры boost.
Если это вызывает преждевременную оптимизацию, раздражающую некоторых людей, я на самом деле согласен, что мне не нужно это для моего текущего проекта. Но мне любопытно, если это возможно.