I'm using the pimpl idiom heavily in my code, mostly to reduce compilation time.
I have a situation where I'm calling into a C library. I have a C++ wrapper class which has its interface, and the gory details are all in the impl
, of course:
class some_class {
public:
void some_init();
...
private:
class impl;
std::unique_ptr<impl> m_pimpl;
}
In the cpp file I have to register a callback with the C library where I get to give it a pointer. I want to forward this function call to the corresponding member function. The client (i.e. the user of this function) doesn't have to know about this detail at all:
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);
}
The problem is that some_class::impl
is declared private. I can only think of imperfect solutions:
class impl;
public in the header file. This is not ideal because it really should be private
- it just happens to be an implementation detail that a non-class function needs to see it.from_c_func
in the header file and friend
it. This is not ideal because the implementation details of some_class
are leaking out. Changing the implementation may require changing the header file, which would then recompile a lot of things which don't need recompilation, which would make me unhappy.from_c_func
a pointer to some_class
itself, and then call a function on some_class
. This would require putting that function in the header file, which is again, an implementation detail - and it would have to be public
anyway for the non-friend function to call it.What to do? My best bet so far seems to be #1, but is there any better way?
You may move your function in 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();
}