In the past I've sometimes taken this a step further and defined a pure abstract class plus factory function in the header and then defined a derived implementation class in the source file, kind of a COM lite approach. (Is there an agreed name for this pattern? I don't doubt that, like most things I've invented, it was first thought of in the '60s or '70s. :P )
It's good for libraries because it separates all implementation details from the public interface while adding very little overhead for the library dev. Not so good for smaller utilities which are more natural as header-only classes, though.
These days I don't bother with that kind of messing around until it actually becomes necessary, which it almost never does. I feel like my code's become way simpler over the years.
I wouldn't know, but some Dylan book taught me that, along the abstract-concrete dimension, there are not two, but three kinds of classes:
- concrete, instantiable
- abstract, instantiable
- abstract, not instantiable
where a type <foo> is instantiable if a function make(<foo>) exists (because <foo> is abstract, that function must return an instance of a subclass of <foo>)
That factory function makes your abstract class instantiable.
Also, in Java, Foo would be an interface, and that factory would be a FooFactory.
To save others the arduous trial of googling it like I had to: http://wiki.c2.com/?PimplIdiom
In the past I've sometimes taken this a step further and defined a pure abstract class plus factory function in the header and then defined a derived implementation class in the source file, kind of a COM lite approach. (Is there an agreed name for this pattern? I don't doubt that, like most things I've invented, it was first thought of in the '60s or '70s. :P )
It's good for libraries because it separates all implementation details from the public interface while adding very little overhead for the library dev. Not so good for smaller utilities which are more natural as header-only classes, though.
These days I don't bother with that kind of messing around until it actually becomes necessary, which it almost never does. I feel like my code's become way simpler over the years.