суббота, 3 декабря 2011 г.

Реализация обобщённой pimpl-идиомы от Герба Саттера


Известный гуру C++ поделился своей идеей обобщённой реализации pimpl-идиомы с использованием возможностей нового стандарта. Основная задача, решаемая этой реализацией - это, на самом деле, упростить декларацию классов с pimpl-реализациями и пробросом параметров конструкторов. От реализации интерфейсных методов посредством делегирования разработчик всё равно не избавлен. Но, хоть что-то. :)

GotW #101: Solution:
The solution to GotW #101 is now live.


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...
}; 
}

Что, очевидно, не очень здорово. Если же SomeClass сам расположен в своём пространстве, то ситуация осложняется.

Комментариев нет:

Отправить комментарий