Известный гуру C++ поделился своей идеей обобщённой реализации pimpl-идиомы с использованием возможностей нового стандарта. Основная задача, решаемая этой реализацией - это, на самом деле, упростить декларацию классов с pimpl-реализациями и пробросом параметров конструкторов. От реализации интерфейсных методов посредством делегирования разработчик всё равно не избавлен. Но, хоть что-то. :)
GotW #101: Solution:
Filed under: C++
Для понимания этого материала также полезна эта ссылка:
GotW #100
в которой объясняется общий подход к использованию этой идиомы в разработке.
Но у предложенного Саттером обобщенного класса pimpl есть один существенный недостаток, который практически исключает его использование в реальной разработке.
Заключается он в следующем. Поскольку класс имплементации объявляется внутри шаблонного класса pimpl, то для того, чтобы этот класс определить, необходима полная специализация класса pimpl. А сделать это можно только в том же namespace, в котором pimpl объявлен. На примере.
Положим, мы объявили шаблонный класс pimpl так:
namespace flex_lib
{
template<typename ImplType> class pimpl
{
protected:
class impl_t;
std::unique_ptr<impl_t> m_impl;
protected:
template<typename ... Args>
pimpl(Args&& ... args)
: m_impl(new impl_t(std::forward<Args>(args)...))
{ }
~pimpl() {;}
};
}
и хотим его использовать ну хотя бы для такого класса:
class SomeClass : flex_lib::pimpl<SomeClass>
{
};
В этом случае класс реализации мы можем объявить только в пространстве flex_lib:
namespace flex_lib
{
template<> class pimpl<SomeClass>::impl_t
{
// implementation goes here...
};
}
{
template<> class pimpl<SomeClass>::impl_t
{
// implementation goes here...
};
}
Что, очевидно, не очень здорово. Если же SomeClass сам расположен в своём пространстве, то ситуация осложняется.
Комментариев нет:
Отправить комментарий