How to better organize the code in C++ projects - c++

I'm currently in the process of trying to organize my code in better way.
To do that I used namespaces, grouping classes by components, each having a defined role and a few interfaces (actually Abstract classes).
I found it to be pretty good, especially when I had to rewrite an entire component and I did with almost no impact on the others. (I believe it would have been a lot more difficult with a bunch of mixed-up classes and methods)
Yet I'm not 100% happy with it. Especially I'd like to do a better separation between interfaces, the public face of the components, and their implementations in behind.
I think the 'interface' of the component itself should be clearer, I mean a new comer should understand easily what interfaces he must implement, what interfaces he can use and what's part of the implementation.
Soon I'll start a bigger project involving up to 5 devs, and I'd like to be clear in my mind on that point.
So what about you? how do you do it? how do you organize your code?

Especially I'd like to do a better
separation between interfaces, the
public face of the components, and
their implementations in behind.
I think what you're looking for is the Facade pattern:
A facade is an object that provides a simplified interface to a larger body of code, such as a class library. -- Wikipedia
You may also want to look at the Mediator and Builder patterns if you have complex interactions in your classes.
The Pimpl idiom (aka compiler firewall) is also useful for hiding implementation details and reducing build times. I prefer to use Pimpl over interface classes + factories when I don't need polymorphism. Be careful not to over-use it though. Don't use Pimpl for lightweight types that are normally allocated on the stack (like a 3D point or complex number). Use it for the bigger, longer-lived classes that have dependencies on other classes/libraries that you'd wish to hide from the user.
In large-scale projects, it's important to not use an #include directives in a header file when a simple forward declaration will do. Only put an #include directives in a header file if absolutely necessary (prefer to put #includes in the implementation files). If done right, proper #include discipline will reduce your compile times significantly. The Pimpl idiom can help to move #includes from header files to their corresponding implementation files.
A coherent collection of classes / functions can be grouped together in it's own namespace and put in a subdirectory of your source tree (the subdirectory should have the same name as the library namespace). You can then create a static library subproject/makefile for that package and link it with your main application. This is what I'd consider a "package" in UML jargon. In an ideal package, classes are closely related to each other, but loosely related with classes outside the package. It is helpful to draw dependency diagrams of your packages to make sure there are no cyclical dependencies.

There are two common approaches:
If, apart from the public interface, you only need some helper functions, just put them in an unnamed namespace in the implementation file:
// header:
class MyClass {
// interface etc.
};
// source file:
namespace {
void someHelper() {}
}
// ... MyClass implementation
If you find yourself wanting to hide member functions, consider using the PIMPL idiom:
class MyClassImpl; // forward declaration
class MyClass {
public:
// public interface
private:
MyClassImpl* pimpl;
};
MyClassImpl implements the functionality, while MyClass forwards calls to the public interface to the private implementation.

You might find some of the suggestions in Large Scale C++ Software Design useful. It's a bit dated (published in 1996) but still valuable, with pointers on structuring code to minimize the "recompiling the world when a single header file changes" problem.

Herb Sutter's article on "What's In a Class? - The Interface Principle" presents some ideas that many don't seem to think of when designing interfaces. It's a bit dated (1998) but there's some useful stuff in there, nonetheless.

First declare you variables you may use them in one string declaration also like so.
char Name[100],Name2[100],Name3[100];
using namespace std;
int main(){
}
and if you have a long peice of code that could be used out of the program make it a new function.
likeso.
void Return(char Word[100]){
cout<<Word;
cin.ignore();
}
int main(){
Return("Hello");
}
And I suggest any outside functions and declarations you put into a header file and link it
likeso
Dev-C++ #include "Resource.h"

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.

Why would you want to put a class in an implementation file?

While looking over some code, I ran into the following:
.h file
class ExampleClass
{
public:
// methods, etc
private:
class AnotherExampleClass* ptrToClass;
}
.cpp file
class AnotherExampleClass
{
// methods, etc
}
// AnotherExampleClass and ExampleClass implemented
Is this a pattern or something beneficial when working in c++? Since the class is not broken out into another file, does this work flow promote faster compilation times?
or is this just the style this developer?
This is variously known as the pImpl Idiom, Cheshire cat technique, or Compilation firewall.
Benefits:
Changing private member variables of a class does not require recompiling classes that depend on it, thus make times are faster, and
the FragileBinaryInterfaceProblem is reduced.
The header file does not need to #include classes that are used 'by value' in private member variables, thus compile times are faster.
This is sorta like the way SmallTalk automatically handles classes... more pure encapsulation.
Drawbacks:
More work for the implementor.
Doesn't work for 'protected' members where access by subclasses is required.
Somewhat harder to read code, since some information is no longer in the header file.
Run-time performance is slightly compromised due to the pointer indirection, especially if function calls are virtual (branch prediction for indirect branches is generally poor).
Herb Sutter's "Exceptional C++" books also go into useful detail on the appropriate usage of this technique.
The most common example would be when using the PIMPL pattern or similar techniques. Still, there are other uses as well. Typically, the distinction .hpp/.cpp in C++ is rather (or, at least can be) one of public interface versus private implementation. If a type is only used as part of the implementation, then that's a good reason not to export it in the header file.
Apart from possibly being an implementation of the PIMPL idiom, here are two more possible reason to do this:
Objects in C++ cannot modify their this pointer. As a consequence, they cannot change type in mid-usage. However, ptrToClass can change, allowing an implementation to delete itself and to replace itself with another instance of another subclass of AnotherExampleClass.
If the implementation of AnotherExampleClass depends on some template parameters, but the interface of ExampleClass does not, it is possible to use a template derived from AnotherExampleClass to provide the implementation. This hides part of the necessary, yet internal type information from the user of the interface class.

Recommended approaches for making my code swiggable?

I'm currently refactoring a Tcl plugin library written in C++. Originally the code was hand-written. A second library exists that does the same thing for Java.
The refactored library will be a single C++ library that can be used to create bindings to different languages.
My first tests with SWIG are promising. However, a lot of junk is generated as well. Various base classes and utilities are all exported. These don't make sense from the scripting point of view and only increase clutter.
Possible solutions that I can think of are:
Use #ifndef SWIG in the original codebase to filter out unneeded code
Create a SWIG-compatible wrapper around the API classes.
Differentiate between public and private headers. Public headers are pure abstract base classes that contain no implementation. The private headers inherit and implement them. Only SWIG the public headers.
The opposite of the above solution: inherit a SWIG-compatible class for each API class.
I'm currently leaning towards solution 3 at the moment. However, I'm not really certain so I'd like to know the SO community's opinion on this. Feel free to share your thoughts.
Update
I forgot to list one solution:
Code that should not exported by SWIG should probably not be in the public section of your class.
Perhaps this is the answer. I'll have another look on Monday.
Update
I settled with a solution. See my answer.
Any approach that means that the C++ library becomes less useful to the C++ user is not the ideal solution.
#ifdef SWIG in the middle of .hpp files: Muddies up your C++ with unnecessary cruft, so it's not ideal
SWIG Specific Interface: This is a viable option, but only makes sense if the code you want to expose to SWIG is significantly higher level then the base C++ API.
Public vs Private interface: Might make sense, but again you have to ask at what cost to the C++ user of the API? Are you limiting the public interface too much? Who has access to the private interface? Should the pImpl idiom be considered instead?
SWIG Compatible Class for each interface: Probably more work than necessary.
First and foremost, to keep your SWIG related code separate from the rest of the API.
You probably don't want to import the .hpp files directly into SWIG (if SWIG wasn't considered during the initial design of the library), but if you do, you want to use a SWIG .i file to help you clean up the mess. There are three basic approaches we use, each with different use cases.
First, direct inclusion. This is useful if you know your API is nice and clean and well suited for parsing by SWIG:
// MyClass.i
%{
#include "MyClass.hpp" // included for the generated .cxx file
%}
%include "MyClass.hpp" // included and parsed directly by SWIG
The second case is for code that is most of the way there. This is code that had SWIG taken into consideration, but really needed some stuff for the C++ user that we didn't want to expose to SWIG:
// MyClass.i
%{
#include "MyClass.hpp" // included for the generated .cxx file
%}
%ignore MyClass::someFunction(); // This function really just causes us problems
%include "MyClass.hpp" // included and parsed directly by SWIG
The third case, and probably the one you want to use, is to directly choose which functions you want to expose to SWIG.
// MyClass.i
%{
#include "MyClass.hpp" // included for the generated .cxx file
%}
// With this example we provide exactly as much information to SWIG as we want
// it to have. Want it to know the base class? Add it. Don't want it to know about
// a function? Leave it out. want to add a new function? %extend it.
class MyClass
{
void importantFunction();
void importantFunction2();
}
I'd use apprach #3 too. I'm using a similar approach in my projects, and it is used by COM too (interfaces inherithed by private implementation class).
It is really easy to detect errors and maintain code in that way! Unfortunately you will end implementing all functions as virtual, but it should not be a big issue...
Separating the interface will keep it really clean and understandable!
My final solution: simply SWIG the original code base. In order to avoid generation of non-relevant code I use the following techniques. In order of preference:
Make non-swig code private or protected. If it doesn't need to be swigged, then it probably doesn't need to be public.
If possible, change the original code to make it more compatible with SWIG. I replaced a curiously recurring template pattern with abstract base classes. I was willing to make that sacrifice for SWIG :)
Add %ignore statements to the interface file.
Use #ifndef SWIG to filter it out. I don't like to pollute my original code so I only use this as a last resort.
Concerning my previous ideas:
Create a SWIG-compatible wrapper around the API classes.
Differentiate between public and private headers. Public headers are
pure abstract base classes that
contain no implementation. The private
headers inherit and implement them.
Only SWIG the public headers.
The opposite of the above solution: inherit a SWIG-compatible class for
each API class.
All these solutions require writing SWIG-compatible wrapper code. This is a bit silly because you are ditching SWIG's the strongest selling point: automatic generation of wrapper code. If I write my own wrapper code for SWIG then I might just as well write regular JNI code.
That said, I realize that for some projects writing wrapper code may the most cost-efficient solution. However, I this was not the case in my situation.

DLL library interface

I have a question that bothers me for a long time.
I have a mathematical library, implemented as DLL.
The library implements many types of mathematical functions.
The mathematical functions are implemented in different classes based on their functionality. For example, all functions that implements polynomial equations are under CPolynom, all functions that implements differential equations are under CDifferential.
The DLL has to expose an interface.
Now my question:
Option 1
I can implement in one header file, one interface class which includes all the “sub” interface methods of all practical classes => On one hand, I expose to the outside world only one header file with one class, on the other hand this class might be huge, including interface methods which are not related (i.e. someone wants the CPolynom functionality, he/she will have to include huge header file and construct huge interface class)
Option 2
I can implement interface class for each class in different header file.
=> On one hand I split classes to different files based on functionality. If someone wants a specific functionality, he/she will have to include only the relevant file.
On the other hand, I can end up with many header files introduced to the outside world.
Which approach counts as more professional, more correct in software design discipline?
Thank you,
David
I generally implement one header per class. If you find yourself always needing a shotgun blast of headers because you need "one from column A and two from column B", that generally implies some sort of design code smell. For instance, you have a single responsibility spread across several classes instead of concentrated in a single class.
Well, you could always go for option 2 and create a header, that will include all other headers, so that way, if someone doesn't care, he will just include 1 big header, otherwise, he will be able to include only what he needs.
Personally, I don't see anything wrong with one big header, when I try to use small headers as an user, I always have problems like "I need only 1 function from header X, 2 from header Y, ...." and after all, I end up with 15 includes to one library in each *.cpp file, which is annoying (so I actually create one big header myself :) ).
I think that you should implement interface for each class and put them in one header file. No need to produce lot of library headers in the world of precompiled headers.
One header (or few, if there is a lot of interfaces and you can group them logically), but separate classes is an option too. Don't make one huge class with bunch of methods like you were going to do in option 1.
The size of the header file is relevant only in terms of how long it takes to compile. Unused declarations will not impact performance, and your code size is already impacted by shipping all the functions in a DLL instead of statically linking only the needed functions.
Have you considered putting a COM interface on the library? Instead of shipping a separate .h file your users can simply:
#import "mathFunctions.dll" named_guids
Automatically declared smart pointers then make the functions usable with no further manual declarations or even cleanup. You can define your documentation in the IDL, which will then appear in tooltips in the IDE when your clients go to use your code. Your code is also reusable in all Microsoft languages from VB3-6 and wscript and .Net.
double myFunc(double x)
{
double a=1, b=2, c=3, y=0;
MathLib::PolynomPtr polynom(CLSID_CPolynom, 0, CLSCTX_INPROC_SERVER);
y = polynom->someFunction(a, b, c, x); // use it somehow
return y;
}
Used in-proc, COM adds only about 16 cycles of overhead to the execution of each function. Because it's a smart pointer, you do not have to clean it up. And I didn't include it above, but as with anything external you should add basic try/catch functionality wrappers:
catch (_com_error &e) { printf("COM error: %08x %s\n", e.Error(), e.Description()) };
Option 2 would look natural and professional to everybody.
This is the way the large majority of libraries are done.
However, grouping small related classes in the same header (but still having several headers for the whole API) sounds very reasonable.
The biggest disadvantages I see of option 1 are:
- Everything in a big class might be difficult to handle: when a developer is busy on using CPolynom, having its declaration lost between CDifferential and other class would be painful.
- Using a namespace is more appropriate to aggregate classes, than a bigger, "mother" class.
In short, I would choose option 2, with all classes under the library namespace.

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.