Введение
Питер Вайнхарт описывает, как спроектировать базовый базовый класс intrusive_ptr с использованием CRTP , который можно использовать следующим образом:
class foo : intrusive_base<foo>
{
// foo-specific code.
};
При таком подходеограничение на то, что все foo
объекты имеют счетчик ссылок.Предположим, что мы сохраняем foo
иногда по значению и хотим платить цену счетчика ссылок только тогда, когда у нас есть указатель.Например, иногда мы хотели бы создать foo
экземпляров и просто переместить их, а иногда мы хотим выделить foo
в куче.
Концептуально, правильным механизмом для этого сценария является std::shared_ptr
.Однако существуют определенные сценарии, требующие необработанных указателей, которые будут вызывать навязчивый указатель, например, при передаче указателей через API C, которые принимают указатели void.В этом случае можно было бы «ref» указатель перед передачей его непрозрачному API и «unref» при его возврате.
Имея контроль над foo
, вероятно, лучшим способом было бы использовать политикуна основе реализации и имеют базовую версию с подсчетом ссылок foo
.Не имея контроля над foo
, альтернативный дизайн мог бы инвертировать отношения наследования:
template <typename Base>
class intrusive : public Base
{
// ?
private:
std::atomic_size_t ref_count_;
};
typedef intrusive<foo> intrusive_foo;
// Assume boost::intrusive_ptr as intrusive pointer implementation
boost::intrusive_ptr<intrusive_foo> x = new intrusive_foo;
{
auto y = x; // Semantics: boost::intrusive_ptr_add_ref(x.get())
// At scope exit: boost::intrusive_ptr_release(x.get())
}
В вышеупомянутой статье Питер говорит, что такая "обобщенная реализация [intrusive
] будет использовать C ++ 0x вариационные шаблоны и совершенную пересылку. "
Вопрос
Как будет выглядеть реализация такого универсального класса intrusive
?Я мог видеть, что он может извлечь выгоду из наследующих C ++ 11 конструкторов, но мне неясно, как на самом деле можно реализовать тело intrusive
, используя упомянутые инструменты.