C++: Hiding class implementation detail generic It always bugged me that you would have to write your private class members inside the header files in C++. This means that everytime you change you implementation, client code has to be rebuild.

I found thise site which describes how to hide implementation detail in C++: http://www.octopull.demon.co.uk/c++/implementation_hiding.html

However I also wanted the code to be generic, so that I didn't have to rewrite the same code for each and every class I create. Here is what I got:

#define TL_UTILS_IMPL_DECL(member) \
    private: \
        class impl; \
        impl* member;

#define TL_UTILS_IMPL_START(t_class, parent) \
    class t_class::impl \
    { \
        public: \
            t_class* parent; \
            impl(t_class* self) \
                : parent(self) \
            {}

#define TL_UTILS_IMPL_END() \
    };

#define TL_UTILS_IMPL_INIT(member) \
    member = new impl(this);

#define TL_UTILS_IMPL_TERM(member) \
    delete member;

#define TL_UTILS_IMPL_PREFIX(t_class) \
    t_class::impl::


Example usage:

// Header file:
    class foo
    {
            TL_UTILS_IMPL_DECL(m)

        public:
            foo();
            ~foo();
    };

// Source file:
    TL_UTILS_IMPL_START(foo, p)
        void bar();
    TL_UTILS_IMPL_END()

    foo::foo()
    {
        TL_UTILS_IMPL_INIT(m)

        // from here on we can use the private
        // data and methods stored in m
        m-&gt;bar();
    }

    foo::~for()
    {
        TL_UTILS_IMPL_TERM(m)
    }

    void TL_UTILS_IMPL_PREFIX(foo) bar()
    {
        // do something useful
        // use p as a pointer to the parent class instance
    }


I always hear that preprocessor macros are dirty and should not be used in C++, and I agree to some degree. However I could not realize what I wanted using templates.

So what do you think?


Is the use of preprocessor macros justified here?
Is the code safe?
Any improvements you can think of?
Is the use of preprocessor macros justified here?


To me it seems like overkill. The only non-trivial macro is TL_UTILS_IMPL_START, and that will almost certainly never be useful - usually, the impl class won't need a back-pointer to its wrapper class, but will need other constructor arguments, so you'll usually have to write your own class-specific constructor and initialiser anyway. The other macros are just as verbose as, and much less self-explanatory than, the code they replace.


  Is the code safe?


You need to apply the "Rule of Three" - either implement, or remove, the copy constructor and copy assignment operator. I generally use boost::scoped_ptr for the implementation pointer, which sorts this out for me (as well as removing the need for a destructor body).