2016-02-16 6 views
0

Я использую pimpl idiom в моем коде, в основном для сокращения времени компиляции.Как предотвратить детали impl из того, что они находятся в файле заголовка, когда глобальной функции нужен указатель на impl?

У меня есть ситуация, когда я звоню в библиотеку C. У меня есть ++ класса-оболочки C, который имеет свой интерфейс, и окровавленные детали все в impl, конечно:

class some_class { 
public: 
    void some_init(); 
    ... 
private: 
    class impl; 
    std::unique_ptr<impl> m_pimpl; 
} 

В файле CPP я должен зарегистрировать обратный вызов с библиотекой C, где я получаю, чтобы дать это указатель. Я хочу передать этот вызов функции соответствующей функции-члену. Клиент (т.е. пользователь этой функции) не должны знать об этом подробно на всех:

static void from_c_func(void *ptr_to_class_impl) { 
    static_cast<some_class::impl *>(ptr_to_class_impl)->from_c_func(); 
} 

void some_class::some_init() { 
    create_c_thing(static_cast<void *>(this->m_pimpl.get()), from_c_func); 
} 

Проблема заключается в том, что some_class::impl объявлена ​​частным. Я могу только думать о несовершенных решениях:

  1. Сделать class impl; общедоступным в файле заголовка. Это не идеально, потому что на самом деле это должно быть private - это просто детали реализации, которые должна видеть функция неклассов.
  2. Поместить from_c_func в файл заголовка и friend его. Это не идеально, потому что детали реализации some_class протекают. Изменение реализации может потребовать изменения файла заголовка, который затем перекомпилирует много вещей, которые не нуждаются в перекомпиляции, что сделало бы меня несчастным.
  3. Дает from_c_func указатель на some_class сам, а затем вызывается функция на some_class. Для этого потребуется поместить эту функцию в заголовочный файл, что опять-таки, деталь реализации - и в любом случае для функции non-friend это должно быть public.

Что делать? Кажется, мой лучший выбор - №1, но есть ли лучший способ?

+0

Обычно, все это пойти в 'impl'. поэтому 'some_class :: fun' просто переходит в' m_pimpl-> fun'. – Jarod42

+1

Здесь немного поздно, но не поможет ли это сделать статическую void from_c_func (..) 'статическую функцию-член' impl'? –

+0

Вы можете сделать статичность 'from_c_func' в' some_class', которая также даст ему доступ к 'impl'. – dasblinkenlight

ответ

2

Вы можете переместить функцию в impl

static void some_class::impl::from_c_func(void *ptr_to_class_impl) { 
    static_cast<some_class::impl *>(ptr_to_class_impl)->from_c_func(); 
} 
+0

Ahh да, конечно ... ваш комментарий заставил меня посмотреть ответ. Благодаря! Что-то здесь не связывалось. – Claudiu