Я использую идиома в моем коде, в основном для сокращения времени компиляции.
У меня есть ситуация, когда я звоню в библиотеку 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
объявлен частным Я могу думать только о несовершенных решениях:
class impl;
public в заголовочном файле. Это не идеально, потому что это действительно должно быть private
— это просто деталь реализации, которую не-классная функция должна увидеть.from_c_func
в заголовочном файле и friend
Это. Это не идеально, потому что детали реализации some_class
просачиваются. Изменение реализации может потребовать изменения файла заголовка, который затем перекомпилирует много вещей, которые не нуждаются в перекомпиляции, что сделает меня несчастным.from_c_func
указатель на some_class
сам, а затем вызвать функцию на some_class
, Для этого потребуется поместить эту функцию в заголовочный файл, что опять-таки является деталью реализации — и это должно быть public
во всяком случае для функции не-друга, чтобы вызвать его.Что делать? Моя лучшая ставка до сих пор, кажется, # 1, но есть ли лучший способ?
Вы можете перенести свою функцию в 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();
}
Других решений пока нет …