Hiding library dependencies from library users - c++

Consider I'm writting a static library. Let it has a class Foo
// mylib.h
#include <dependency_header_from_other_static_library.h>
class Foo {
// ...
private:
type_from_dependent_library x;
}
As you can see this library (let call it mylib) depends on another library. It compiles well. But when user compile it's code (that uses Foo and includes mylib.h) and linking with my lib the compilation fails, because user need to have dependency_header_from_other_static_library.h header file to compile code as well.
I want to hide this dependency from the user. How this can be done? The one thing that comes to mind is a PIMPL idiom. Like:
// mylib.h
#include <dependency_header_from_other_static_library.h>
class Foo {
// ...
private:
class FooImpl;
boost::shared_ptr<FooImpl> impl_;
}
// mylib_priv.h
class FooImpl {
// ...
private:
type_from_dependent_library x;
}
But it requires me to duplicate the interface of the class Foo in FooImpl. And, is it an overkill to use PIMPL in my case?
Thanks.

When decoupling a header from other headers, there are a few approaches you might be able to use:
If the used library makes a promise about how it declares its types, you may be able to forward declare the needed types in your header. Of course, this still means you can only refer to these types as pointers or in function signatures in the header but this may be good enough. For example, if the used library promises to have a class LibraryType that you need to use, you can do something like this:
// Foo.h
class LibraryType;
class Foo {
// ...
LibraryType* data;
};
This may cut you the necessary slack to use the type without including its header and without jumping through a PImpl approach.
If the library doesn't make a promise about how it declares it types you may use void* to refer to the corresponding types. Of course, this means that whenever you access the data in your implementation, you'll need to cast the void* to the appropriate type. Since the type is statically known, using static_cast<LibraryType*> is perfectly fine, i.e., there isn't any overhead due to the cast, but it is still relatively painful to do.
The other alternative is, of course, to use the PImpl idiom. If you type provides any reasonably service, it will probably change the interface quite a bit and it shouldn't amount much to replicating the interface between the class itself and the privately declared type. Also, note that the private type is just a data container, i.e., it is reasonably to just make it a struct and have no protection to its accesses. The only real issue is that you need to make sure that the type's definition is visible at the point where the destructor is called. Using std::shared_ptr<T>(new T(/*...*)) arranges for this.
Effectively, all three approaches do the same thing although with slightly different techniques: they provide you an opaque handle to be used in the header file whose definition is only known to the implementation. This way, the client of the library doesn't need to include the corresponding header files. However, unless the symbols are resolved when building the library, it would still be necessary for the client to have access to the used library.

Related

Is forward declaring a class a correct way to hide the implementation? [duplicate]

This question already has answers here:
Is the PIMPL idiom really used in practice?
(12 answers)
Closed 8 years ago.
Backgrounder:
The PIMPL Idiom (Pointer to IMPLementation) is a technique for implementation hiding in which a public class wraps a structure or class that cannot be seen outside the library the public class is part of.
This hides internal implementation details and data from the user of the library.
When implementing this idiom why would you place the public methods on the pimpl class and not the public class since the public classes method implementations would be compiled into the library and the user only has the header file?
To illustrate, this code puts the Purr() implementation on the impl class and wraps it as well.
Why not implement Purr directly on the public class?
// header file:
class Cat {
private:
class CatImpl; // Not defined here
CatImpl *cat_; // Handle
public:
Cat(); // Constructor
~Cat(); // Destructor
// Other operations...
Purr();
};
// CPP file:
#include "cat.h"
class Cat::CatImpl {
Purr();
... // The actual implementation can be anything
};
Cat::Cat() {
cat_ = new CatImpl;
}
Cat::~Cat() {
delete cat_;
}
Cat::Purr(){ cat_->Purr(); }
CatImpl::Purr(){
printf("purrrrrr");
}
I think most people refer to this as the Handle Body idiom. See James Coplien's book Advanced C++ Programming Styles and Idioms. It's also known as the Cheshire Cat because of Lewis Caroll's character that fades away until only the grin remains.
The example code should be distributed across two sets of source files. Then only Cat.h is the file that is shipped with the product.
CatImpl.h is included by Cat.cpp and CatImpl.cpp contains the implementation for CatImpl::Purr(). This won't be visible to the public using your product.
Basically the idea is to hide as much as possible of the implementation from prying eyes.
This is most useful where you have a commercial product that is shipped as a series of libraries that are accessed via an API that the customer's code is compiled against and linked to.
We did this with the rewrite of IONA's Orbix 3.3 product in 2000.
As mentioned by others, using his technique completely decouples the implementation from the interface of the object. Then you won't have to recompile everything that uses Cat if you just want to change the implementation of Purr().
This technique is used in a methodology called design by contract.
Because you want Purr() to be able to use private members of CatImpl. Cat::Purr() would not be allowed such an access without a friend declaration.
Because you then don't mix responsibilities: one class implements, one class forwards.
For what is worth, it separates the implementation from the interface. This is usually not very important in small size projects. But, in large projects and libraries, it can be used to reduce the build times significantly.
Consider that the implementation of Cat may include many headers, may involve template meta-programming which takes time to compile on its own. Why should a user, who just wants to use the Cat have to include all that? Hence, all the necessary files are hidden using the pimpl idiom (hence the forward declaration of CatImpl), and using the interface does not force the user to include them.
I'm developing a library for nonlinear optimization (read "lots of nasty math"), which is implemented in templates, so most of the code is in headers. It takes about five minutes to compile (on a decent multi-core CPU), and just parsing the headers in an otherwise empty .cpp takes about a minute. So anyone using the library has to wait a couple of minutes every time they compile their code, which makes the development quite tedious. However, by hiding the implementation and the headers, one just includes a simple interface file, which compiles instantly.
It does not necessarily have anything to do with protecting the implementation from being copied by other companies - which wouldn't probably happen anyway, unless the inner workings of your algorithm can be guessed from the definitions of the member variables (if so, it is probably not very complicated and not worth protecting in the first place).
If your class uses the PIMPL idiom, you can avoid changing the header file on the public class.
This allows you to add/remove methods to the PIMPL class, without modifying the external class's header file. You can also add/remove #includes to the PIMPL too.
When you change the external class's header file, you have to recompile everything that #includes it (and if any of those are header files, you have to recompile everything that #includes them, and so on).
Typically, the only reference to a PIMPL class in the header for the owner class (Cat in this case) would be a forward declaration, as you have done here, because that can greatly reduce the dependencies.
For example, if your PIMPL class has ComplicatedClass as a member (and not just a pointer or reference to it) then you would need to have ComplicatedClass fully defined before its use. In practice, this means including file "ComplicatedClass.h" (which will also indirectly include anything ComplicatedClass depends on). This can lead to a single header fill pulling in lots and lots of stuff, which is bad for managing your dependencies (and your compile times).
When you use the PIMPL idiom, you only need to #include the stuff used in the public interface of your owner type (which would be Cat here). Which makes things better for people using your library, and means you don't need to worry about people depending on some internal part of your library - either by mistake, or because they want to do something you don't allow, so they #define private public before including your files.
If it's a simple class, there's usually isn't any reason to use a PIMPL, but for times when the types are quite big, it can be a big help (especially in avoiding long build times).
Well, I wouldn't use it. I have a better alternative:
File foo.h
class Foo {
public:
virtual ~Foo() { }
virtual void someMethod() = 0;
// This "replaces" the constructor
static Foo *create();
}
File foo.cpp
namespace {
class FooImpl: virtual public Foo {
public:
void someMethod() {
//....
}
};
}
Foo *Foo::create() {
return new FooImpl;
}
Does this pattern have a name?
As someone who is also a Python and Java programmer, I like this a lot more than the PIMPL idiom.
Placing the call to the impl->Purr inside the .cpp file means that in the future you could do something completely different without having to change the header file.
Maybe next year they discover a helper method they could have called instead and so they can change the code to call that directly and not use impl->Purr at all. (Yes, they could achieve the same thing by updating the actual impl::Purr method as well, but in that case you are stuck with an extra function call that achieves nothing but calling the next function in turn.)
It also means the header only has definitions and does not have any implementation which makes for a cleaner separation, which is the whole point of the idiom.
We use the PIMPL idiom in order to emulate aspect-oriented programming where pre, post and error aspects are called before and after the execution of a member function.
struct Omg{
void purr(){ cout<< "purr\n"; }
};
struct Lol{
Omg* omg;
/*...*/
void purr(){ try{ pre(); omg-> purr(); post(); }catch(...){ error(); } }
};
We also use a pointer-to-base class to share different aspects between many classes.
The drawback of this approach is that the library user has to take into account all the aspects that are going to be executed, but only sees his/her class. It requires browsing the documentation for any side effects.
I just implemented my first PIMPL class over the last couple of days. I used it to eliminate problems I was having, including file *winsock2.*h in Borland Builder. It seemed to be screwing up struct alignment and since I had socket things in the class private data, those problems were spreading to any .cpp file that included the header.
By using PIMPL, winsock2.h was included in only one .cpp file where I could put a lid on the problem and not worry that it would come back to bite me.
To answer the original question, the advantage I found in forwarding the calls to the PIMPL class was that the PIMPL class is the same as what your original class would have been before you pimpl'd it, plus your implementations aren't spread over two classes in some weird fashion. It's much clearer to implement the public members to simply forward to the PIMPL class.
Like Mr Nodet said, one class, one responsibility.
I don't know if this is a difference worth mentioning but...
Would it be possible to have the implementation in its own namespace and have a public wrapper / library namespace for the code the user sees:
catlib::Cat::Purr(){ cat_->Purr(); }
cat::Cat::Purr(){
printf("purrrrrr");
}
This way all library code can make use of the cat namespace and as the need to expose a class to the user arises a wrapper could be created in the catlib namespace.
I find it telling that, in spite of how well-known the PIMPL idiom is, I don't see it crop up very often in real life (e.g., in open source projects).
I often wonder if the "benefits" are overblown; yes, you can make some of your implementation details even more hidden, and yes, you can change your implementation without changing the header, but it's not obvious that these are big advantages in reality.
That is to say, it's not clear that there's any need for your implementation to be that well hidden, and perhaps it's quite rare that people really do change only the implementation; as soon as you need to add new methods, say, you need to change the header anyway.

PIMPL idiom VS forward declaration

I have read a bit about the PIMPL idiom and was wondering - is it any different to forward declaring the dependent type(s)?
If so:
When will I prefer using that over a forward declaration?
Do these two versions differ in their compilation time?
Is one of them more scalable than the other?
Specifically consider a class Foo that is dependent on Bar (should have a member of type Bar).
Foo.h with forward declaration:
class Bar;
class Foo
{
public:
Foo();
private:
Bar* _bar;
};
Foo.h with PIMPL:
class Foo
{
public:
Foo();
private:
/* FooImpl is an incomplete type at this point.
* Implemented in cpp file and has a member of type Bar.
*/
class FooImpl;
FooImpl* _fooImpl;
}
Please ignore the raw pointer usage - I was just trying to make a point.
I have read a bit about the PIMPL idiom and was wondering - is it any different to forward declaring the dependent type(s)?
Yes, they are different. The PIMPL idiom (it has several names) is specifically about hiding the implementation detail from the client code. This could be done for a number of reasons, including (but not limited to);
isolating the rebuild when class details change (they are hidden)
minimising required or conflicting header inclusions
a general build time reduction
minimal export requirements (although abstract classes could be used for this purpose as well)
easier control over implementation detail that varies over multiple targets or platforms
In essence, the PIMPL offers a technique to "hide" the implementation from the client code - whenever that may be needed.
When will I prefer using [PIMPL] over forward declaration?
This is really about intent - your code is about abstractions - take care of those abstractions, nuture them and protect them, they will serve you well.
The question becomes - which one better represents your intent? I would venture to say that the FooImpl is better, I sense your intent is to hide the implementation of the class from the client and this implementation better represents that intent (since FooImpl is not accessible to the client).
If your intent to is to use Bar elsewhere in the code, outside of the class Foo, then that implementation is better because that is the intent and that implementation allows you to do that.
Do these two versions differ in their compilation time?
I doubt that. The implementation of Bar and FooImpl are not visible outside the translation unit they are defined in.
Is one of them more scalable than the other?
Not really, no. In some generic sense, the clearer code is, the easier people are able to scale it.
The PIMPL pattern is typically used to completely hide implementation details from code which uses your class.
For example, your class might be wrapping platform-specific functionality. Even if you used forward declarations and/or conditional compilation, you would end up exposing platform-specific code in your header file. This means that any code using your class would end up with a header-dependency on those types as well, and it means your class would potentially change depending on the platform (e.g. the size might be different).
The PIMPL pattern would let you keep all the platform-specific details hidden away in the implementation file (typically *.cpp or similar). This means no other code anywhere else in the program can directly see it, keeping your wrapper class clean and consistent across all platforms.
That's just one example of where PIMPL comes in handy, but there are other uses for it too.
It's also worth noting that not everything can be forward-declared, and forward declarations often require making undesirable concessions, such as using pointers or references everywhere.

Hide class type in header

I'm not sure if this is even possible, but here goes:
I have a library whose interface is, at best, complex. Unfortunately, not only is it a 3rd-party library (and far too big to rewrite), I'm using a few other libraries that are dependent on it. So that interface has to stay how it is.
To solve that, I'm trying to essentially wrap the interface and bundle all the dependencies' interfaces into fewer, more logical classes. That part is going fine and works great. Most of the wrapper classes hold a pointer to an object of one of the original classes. Like so:
class Node
{
public:
String GetName()
{
return this->llNode->getNodeName();
}
private:
OverlyComplicatedNodeClass * llNode; // low-level node
};
My only problem is the secondary point of this. Beside simplifying the interface, I'd like to remove the requirement for linking against the original headers/libraries.
That's the first difficulty. How can I wrap the classes in such a way that there's no need to include the original headers? The wrapper will be built as a shared-library (dll/so), if that makes it simpler.
The original classes are pointers and not used in any exported functions (although they are used in a few constructors).
I've toyed with a few ideas, including preprocessor stuff like:
#ifdef ACCESSLOWLEVEL
# define LLPtr(n) n *
#else
# define LLPtr(n) void *
#endif
Which is ugly, at best. It does what I need basically, but I'd rather a real solution that that kind of mess.
Some kind of pointer-type magic works, until I ran into a few functions that use shared pointers (some kind of custom SharedPtr<> class providing reference count) and worse yet, a few class-specific shared pointers derived from the basic SharedPtr class (NodePtr, for example).
Is it at all possible to wrap the original library in such a way as to require only my headers to be included in order to link to my dynamic library? No need to link to the original library or call functions from it, just mine. Only problem I'm running into are the types/classes that are used.
The question might not be terribly clear. I can try to clean it up and add more code samples if it helps. I'm not really worried about any performance overhead or anything of this method, just trying to make it work first (premature optimization and all that).
Use the Pimpl (pointer to implementation) idiom. As described, OverlyComplicatedNodeClass is an implementation detail as far as the users of your library are concerned. They should not have to know the structure of this class, or even it's name.
When you use the Pimpl idiom, you replace the OverlyComplicatedNodeClass pointer in your class with a pointer to void. Only you the library writer needs to know that the void* is actually a OverlyComplicatedNodeClass*. So your class declaration becomes:
class Node
{
public:
String GetName();
private:
void * impl;
};
In your library's implementation, initialize impl with a pointer to the class that does the real work:
my_lib.cpp
Node::Node()
: impl(new OverlyComplicatedNodeClass)
{
// ...
};
...and users of your library need never know that OverlyComplicatedNodeClass exists.
There's one potential drawback to this approach. All the code which uses the impl class must be implemented in your library. None if it can be inline. Whether this is a drawback depends very much on your application, so judge for yourself.
In the case of your class, you did have GetName()'s implementation in the header. That must be moved to the library, as with all other code that uses the impl pointer.
Essentially, you need a separate set of headers for each use. One that you use to build your DLL and one with only the exported interfaces, and no mention at all of the encapsulated objects. Your example would look like:
class Node
{
public:
String GetName();
};
You can use preprocessor statements to get both versions in the same physical file if you don't mind the mess.

Forward declare pointers-to-structs in C++

I am using a 3rd party library that has a declaration like this:
typedef struct {} __INTERNAL_DATA, *HandleType;
And I'd like to create a class that takes a HandleType in the constructor:
class Foo
{
Foo(HandleType h);
}
without including the header that defines HandleType. Normally, I'd just forward-declare such a type, but I can't figure out the syntax for this. I really want to say something like:
struct *HandleType;
But that says "Expected identifier before *" in GCC. The only solution I can see is to write my class like this:
struct __INTERNAL_DATA;
class Foo
{
Foo(__INTERNAL_DATA *h);
}
But this relies on internal details of the library. That is to say, it uses the name __INTERNAL_DATA, which is an implementation detail.
It seems like it should be possible to forward-declare HandleType (part of the public API) without using __INTERNAL_DATA (part of the implementation of the library.) Anyone know how?
EDIT: Added more detail about what I'm looking for.
Update:
I am using it in the implementation .cpp of Foo, but I want to avoid including it in my header .h for Foo. Maybe I'm just being too pedantic? :)
Yes you are :) Go ahead with forward declaration.
If HandleType is part of the interface there must be a header declaring that. Use that header.
Your problem is still a vague one. You are trying to protect against something you cannot.
You can add the following line to your client library:
typedef struct INTERNAL_DATA *HandleType;
but, if the name/structure changes you may be in for some casting nastiness.
Try templates:
template <class T>
class Foo
{
Foo(T h);
};
Forward declaration is fine. If you are going to use pointers or references you only need a class (__INTERNAL_DATA) declaration in scope. However, if you are going to use a member function or an object you will need to include the header.
If the type is in a 3rd party library then the big benefit of forward declaration (isolating rebuilds due to changes in headers) is effectively lost.
If you're worried about compilation times (it's a sizeable header) then perhaps you can place it in a precompiled header or just include the relevant header from a library.
E.g. many library headers look like
// library.h
#include "Library/Something.h"
#include "Library/SomethingElse.h"
typedef struct {} __INTERNAL_DATA, *HandleType;
If it is defined like that (all on one line), then __INTERNAL DATA is as much a part of the public interface as HandleType.
However, I don't think __INTERNAL_DATA actually exists. More than likely, HandleType is really (internally) an int. This odd definition is just a way of defining it so that it's the same size as an int, but distinct, so that the compiler give you an error if you try passing an int where you're supposed to pass an HandleType. The library vendor could just as easily have defined it as "int" or "void*", but this way we get some type checking.
Hence __INTERNAL_DATA is just a convention and is not going to change.
UPDATE: The above was a bit of a mental burp... OK, __INTERNAL_DATA definitely does not exist. We know this for a fact, because we can see it's definition as an empty struct. I'm going to guess that the 3rd-party library uses "C" external linkage (no name managling), in which case, just copy the typedef -- it will be fine.
Inside the library itself, HandleType will have a completely different definition; maybe int, maybe "struct MyStruct {.......} *".
If you really, really, really don't want to expose _INTERNAL_DATA to the caller then your only real choice is to use typedef void* HandleType; Then inside your library you can do anything you want including changing the entire implementation of *HandleType.
Just create a helper function to access you real data.
inline _INTERNAL_DATA* Impl(HandleType h) {
return static_cast<_INTERNAL_DATA*>(h);
}
I'm not quite sure what you're going for, but the following will work without including the actual header file:
// foo.h
class Foo
{
public:
template<typename T>Foo(T* h) { /* body of constructor */ }
};
Mind you, you will still have to have access the public members of __INTERNAL_DATA within the body of the constructor.
edit: as pointed out by James Curran, the __INTERNAL_DATA structure has no members, so it can be used, as above, with no problems.

Why should the "PIMPL" idiom be used? [duplicate]

This question already has answers here:
Is the PIMPL idiom really used in practice?
(12 answers)
Closed 8 years ago.
Backgrounder:
The PIMPL Idiom (Pointer to IMPLementation) is a technique for implementation hiding in which a public class wraps a structure or class that cannot be seen outside the library the public class is part of.
This hides internal implementation details and data from the user of the library.
When implementing this idiom why would you place the public methods on the pimpl class and not the public class since the public classes method implementations would be compiled into the library and the user only has the header file?
To illustrate, this code puts the Purr() implementation on the impl class and wraps it as well.
Why not implement Purr directly on the public class?
// header file:
class Cat {
private:
class CatImpl; // Not defined here
CatImpl *cat_; // Handle
public:
Cat(); // Constructor
~Cat(); // Destructor
// Other operations...
Purr();
};
// CPP file:
#include "cat.h"
class Cat::CatImpl {
Purr();
... // The actual implementation can be anything
};
Cat::Cat() {
cat_ = new CatImpl;
}
Cat::~Cat() {
delete cat_;
}
Cat::Purr(){ cat_->Purr(); }
CatImpl::Purr(){
printf("purrrrrr");
}
I think most people refer to this as the Handle Body idiom. See James Coplien's book Advanced C++ Programming Styles and Idioms. It's also known as the Cheshire Cat because of Lewis Caroll's character that fades away until only the grin remains.
The example code should be distributed across two sets of source files. Then only Cat.h is the file that is shipped with the product.
CatImpl.h is included by Cat.cpp and CatImpl.cpp contains the implementation for CatImpl::Purr(). This won't be visible to the public using your product.
Basically the idea is to hide as much as possible of the implementation from prying eyes.
This is most useful where you have a commercial product that is shipped as a series of libraries that are accessed via an API that the customer's code is compiled against and linked to.
We did this with the rewrite of IONA's Orbix 3.3 product in 2000.
As mentioned by others, using his technique completely decouples the implementation from the interface of the object. Then you won't have to recompile everything that uses Cat if you just want to change the implementation of Purr().
This technique is used in a methodology called design by contract.
Because you want Purr() to be able to use private members of CatImpl. Cat::Purr() would not be allowed such an access without a friend declaration.
Because you then don't mix responsibilities: one class implements, one class forwards.
For what is worth, it separates the implementation from the interface. This is usually not very important in small size projects. But, in large projects and libraries, it can be used to reduce the build times significantly.
Consider that the implementation of Cat may include many headers, may involve template meta-programming which takes time to compile on its own. Why should a user, who just wants to use the Cat have to include all that? Hence, all the necessary files are hidden using the pimpl idiom (hence the forward declaration of CatImpl), and using the interface does not force the user to include them.
I'm developing a library for nonlinear optimization (read "lots of nasty math"), which is implemented in templates, so most of the code is in headers. It takes about five minutes to compile (on a decent multi-core CPU), and just parsing the headers in an otherwise empty .cpp takes about a minute. So anyone using the library has to wait a couple of minutes every time they compile their code, which makes the development quite tedious. However, by hiding the implementation and the headers, one just includes a simple interface file, which compiles instantly.
It does not necessarily have anything to do with protecting the implementation from being copied by other companies - which wouldn't probably happen anyway, unless the inner workings of your algorithm can be guessed from the definitions of the member variables (if so, it is probably not very complicated and not worth protecting in the first place).
If your class uses the PIMPL idiom, you can avoid changing the header file on the public class.
This allows you to add/remove methods to the PIMPL class, without modifying the external class's header file. You can also add/remove #includes to the PIMPL too.
When you change the external class's header file, you have to recompile everything that #includes it (and if any of those are header files, you have to recompile everything that #includes them, and so on).
Typically, the only reference to a PIMPL class in the header for the owner class (Cat in this case) would be a forward declaration, as you have done here, because that can greatly reduce the dependencies.
For example, if your PIMPL class has ComplicatedClass as a member (and not just a pointer or reference to it) then you would need to have ComplicatedClass fully defined before its use. In practice, this means including file "ComplicatedClass.h" (which will also indirectly include anything ComplicatedClass depends on). This can lead to a single header fill pulling in lots and lots of stuff, which is bad for managing your dependencies (and your compile times).
When you use the PIMPL idiom, you only need to #include the stuff used in the public interface of your owner type (which would be Cat here). Which makes things better for people using your library, and means you don't need to worry about people depending on some internal part of your library - either by mistake, or because they want to do something you don't allow, so they #define private public before including your files.
If it's a simple class, there's usually isn't any reason to use a PIMPL, but for times when the types are quite big, it can be a big help (especially in avoiding long build times).
Well, I wouldn't use it. I have a better alternative:
File foo.h
class Foo {
public:
virtual ~Foo() { }
virtual void someMethod() = 0;
// This "replaces" the constructor
static Foo *create();
}
File foo.cpp
namespace {
class FooImpl: virtual public Foo {
public:
void someMethod() {
//....
}
};
}
Foo *Foo::create() {
return new FooImpl;
}
Does this pattern have a name?
As someone who is also a Python and Java programmer, I like this a lot more than the PIMPL idiom.
Placing the call to the impl->Purr inside the .cpp file means that in the future you could do something completely different without having to change the header file.
Maybe next year they discover a helper method they could have called instead and so they can change the code to call that directly and not use impl->Purr at all. (Yes, they could achieve the same thing by updating the actual impl::Purr method as well, but in that case you are stuck with an extra function call that achieves nothing but calling the next function in turn.)
It also means the header only has definitions and does not have any implementation which makes for a cleaner separation, which is the whole point of the idiom.
We use the PIMPL idiom in order to emulate aspect-oriented programming where pre, post and error aspects are called before and after the execution of a member function.
struct Omg{
void purr(){ cout<< "purr\n"; }
};
struct Lol{
Omg* omg;
/*...*/
void purr(){ try{ pre(); omg-> purr(); post(); }catch(...){ error(); } }
};
We also use a pointer-to-base class to share different aspects between many classes.
The drawback of this approach is that the library user has to take into account all the aspects that are going to be executed, but only sees his/her class. It requires browsing the documentation for any side effects.
I just implemented my first PIMPL class over the last couple of days. I used it to eliminate problems I was having, including file *winsock2.*h in Borland Builder. It seemed to be screwing up struct alignment and since I had socket things in the class private data, those problems were spreading to any .cpp file that included the header.
By using PIMPL, winsock2.h was included in only one .cpp file where I could put a lid on the problem and not worry that it would come back to bite me.
To answer the original question, the advantage I found in forwarding the calls to the PIMPL class was that the PIMPL class is the same as what your original class would have been before you pimpl'd it, plus your implementations aren't spread over two classes in some weird fashion. It's much clearer to implement the public members to simply forward to the PIMPL class.
Like Mr Nodet said, one class, one responsibility.
I don't know if this is a difference worth mentioning but...
Would it be possible to have the implementation in its own namespace and have a public wrapper / library namespace for the code the user sees:
catlib::Cat::Purr(){ cat_->Purr(); }
cat::Cat::Purr(){
printf("purrrrrr");
}
This way all library code can make use of the cat namespace and as the need to expose a class to the user arises a wrapper could be created in the catlib namespace.
I find it telling that, in spite of how well-known the PIMPL idiom is, I don't see it crop up very often in real life (e.g., in open source projects).
I often wonder if the "benefits" are overblown; yes, you can make some of your implementation details even more hidden, and yes, you can change your implementation without changing the header, but it's not obvious that these are big advantages in reality.
That is to say, it's not clear that there's any need for your implementation to be that well hidden, and perhaps it's quite rare that people really do change only the implementation; as soon as you need to add new methods, say, you need to change the header anyway.