Как предотвратить детализацию 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; public в заголовочном файле. Это не идеально, потому что это действительно должно быть private — это просто деталь реализации, которую не-классная функция должна увидеть.
  2. Положил from_c_func в заголовочном файле и friend Это. Это не идеально, потому что детали реализации some_class просачиваются. Изменение реализации может потребовать изменения файла заголовка, который затем перекомпилирует много вещей, которые не нуждаются в перекомпиляции, что сделает меня несчастным.
  3. Дать from_c_func указатель на some_class сам, а затем вызвать функцию на some_class, Для этого потребуется поместить эту функцию в заголовочный файл, что опять-таки является деталью реализации — и это должно быть public во всяком случае для функции не-друга, чтобы вызвать его.

Что делать? Моя лучшая ставка до сих пор, кажется, # 1, но есть ли лучший способ?

0

Решение

Вы можете перенести свою функцию в 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();
}
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]