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->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?