Search code examples
c++pimpl-idiom

C++ pimpl idiom: return impl pointer in getter of API class


I use the pimpl idiom for classes in the public API of my library to benefit from it's properties like ABI stability. In my non-public code it would be convenient to have access to the impl object to directly operate on it.

Is it considered bad practice to add a getter to the API class to return the impl pointer? Why?

The client of my library couldn't use the impl obj anyway as its interface is non-public. My library internal code, on the other hand, can now operate on the impl obj.

public.h:

class PublicClass{
    struct Impl;
    Impl* m_impl;
public:
    Impl* getImpl();
};

impl.h:

struct Impl{
    int foo();
};

main.cpp:

#include "public.h"
#include "impl.h"

int main(){
    PublicClass p;
    auto pimpl = p.getImpl();
    auto interestingVal = pimpl->foo();
}

Just a design question.


Solution

  • As always, this depends on an exact situation. Some examples:

    • A very common case is when you need non-public access in unit-tests, to test some functionality that is not directly exposed to users. If this is the case, then go forward and obtain direct access to the impl. (Although in this particular case you probably can just write unit-tests for Impl class itself.)
    • If there is a group of (a few) tightly coupled classes that actually serve as one "design-unit", then it is also OK to use getImpl between these classes. E.g. this may be class PublicService and class PublicClassRequest, and the request may need to access impl of the service, or vice versa.

    However, if a lot of different classes depend on your getImpl, then you should rethink your design.

    Basically, I would say that you should make your getImpl private, and then friend the users of getImpl, with the standard attitude to friends (see, e.g., https://isocpp.org/wiki/faq/friends#friends-and-encap).