‹— back

When your stack-allocated pimpls pop

You looked at your beautiful Pimpl implementation and decided, it's too good not to use, everything will be pimpled to hell and beyond. A few ints here, a few floats there, it's all fine. You go crazy and add something bigger, like a custom string type or a variable container. You get some invalid memory accesses and crashes and wonder where it all went wrong.

With the barebones implementation we have, the impl pointer is just pointing to some memory in your struct. When dealing with 'plain old data' this is fine, but we're in C++ land with RAII and vtables and other monstrosities. If we need to construct non-trivial types, we need to actually construct them. Bringing in our friend placement new.

Since our blocks of memory are now non-trivial and want the special C++ things, but we're just using 'some memory', we need to do the C++ things ourselves - the full initialisation and release of memory.

Responsibilities

If the Pimpl isn't plain old data any more, how much responsibility should it have? If something in the Pimpl wants to do some complex action or allocate some other memory somewhere, should it be doing that itself?

I'm going with no on this one: the Pimpl is a data container, only a data container. All responsibilities for doing anything with and around the Pimpl should be owned by the parent type. The Pimpl stays dumb and just holds what it's told to.

The exception in my codebase is where the Pimpl is a container for platform-specific implementation, like OpenGL data, in which case the Pimpl provides a platform-agonistic interface to functions that affect its internal data.