I just noticed a new term pimpl idiom, what's the difference between this idiom with Bridge design pattern? I am confused about that.
I also noticed the pimpl idiom is always used for swap function, what's that? Could anybody give me an example?
PIMPL is a way of hiding the implementation, primarily to break compilation dependencies.
The Bridge pattern, on the other hand, is a way of supporting multiple implementations.
swap is a standard C++ function for exchanging the values of two objects. If you swap the pointer to the implementation for a different implementation, you are essentially changing the mechanism of the class at runtime.
But in its basic and common form, a class using PIMPL points to a single implementation, so there is no abstract class with distinct subclasses — just one class, forward declared, and compiled elsewhere. Changing the implementation class does not require any recompilation of sources that include the main header.
For example, say you have a lot of private member functions, private enums, and private data. And these private "bits" change fairly frequently as the class is developed and maintained. If the #include dependencies are such that touching this header file causes a large number of sources to be recompiled, you have a good candidate for PIMPL.
So the Bridge pattern is about object-oriented design, while the PIMPL idiom is about physical design of files.
(For more on physical design, I recommend the book Large-Scale C++ Software Design by John Lakos.)
I have used pointer impl to hide implementation details from public interface/include file
Basically interface look like this:
struct Interface {
private:
class Impl;
Impl *pImpl;
};
Then somewhere in inside Interface::Impl is defined and implemented, but details not exposed.
as far as swap, this is the first time I hear it. Can you elaborate on it?
Pimpl: In short the pimpl pattern is really good for hiding the private implementation. If you wanted to expose your header files for clients that needed to build against your public interface but you didn't want to expose your private implementation details you could use the pimpl pattern to hide the details. You would do this for a few reasons but mainly your header file would not have to change when you change your private implementation details change which otherwise would force your clients to have to recompile. In this way you decouple along with hide your private implementation details. Usually you should hold the impl pointer in a RAII container like a unqiue pointer to make sure it is freed upon destruction.
Pimpl
// my_class.h
class my_class {
public:
// public here
private:
class impl; //forward declare impl
unique_ptr<impl> pimpl; // private implementation pointer
};
// my_class.cpp
class my_class::impl { // defined privately here
// ... all private data and functions: all of these
// can now change without recompiling callers ...
};
my_class::my_class(): pimpl( new impl )
{
// ... set impl values ...
my_class& operator=(my_class other);
friend void swap (my_class& lhs, myclass& rhs); // used for assignment
}
Swap probably came up because when you are doing an assignment operator for this class and implementing your own swap routine to assign the members you need to be aware of assigning this pointer as well
my_class& my_class::operator=(my_class other)
{
swap(*this,other);
return *this;
}
void swap ( my_class& lhs, myclass& rhs )
{
using std::swap // now use default swap if override doesn't exist
// call swap for other members
// swap (lhs.data,rhs.data);
// call swap on unique_ptr
lhs.pimpl.swap(rhs.pimpl); // doesn't throw exceptions
}
Bridge is a totally separate pattern that is used to bridge items together. The similarity between the patterns would be that you may have a process method in your class that hides the actual call since it will delegate this call to the contained object that will handle the actual method call. In other words if you had a request interface base class that contained a request implementor base class pointer. Therefore, at run time you could "bridge" the systems by initializing the bridge with a specific request implementor type but someone calling the bridge would just call the process request method which would delegate the call to the specific derived implementor request method at run time. There are several sources on google with nice diagrams that can explain this more clearly as well.
There is currently a Boost library under review that implements the Pimpl pattern. I've cobbled together a few basic examples using the proposed Boost Pimpl implementation if anyone wants a jump on using this code internally:
https://github.com/sean-/Boost.Examples/tree/a148be39abcb21428857aa50495f8c352600741e/pimpl
UPDATE: The above link has been updated to point to the archived version. It doesn't seem likely that Boost.Pimpl will be accepted in to boost at this point in time in favor of std::unique_ptr<> as a viable replacement (albeit less complete than Boost.Pimpl for some less common usecases).
If you have access to C++11, you are probably better off using std::unique_ptr<> as a PIMPL implementation:
class MyClass {
public:
// ...
private:
class Impl;
std::unique_ptr<Impl> impl_;
};
You can see a full example using std::unique_ptr<> in my C++11 reentrant class locking strategy question.
Using std::unique_ptr<>'s swap() method, it becomes convenient and very practical for C++11's move semantics to move the guts of an object from one owner to another. For example, suppose MyClass exports a swap() implementation that just forwards to std::unique_ptr<>'s swap:
void MyClass::swap(MyClass *c) { impl_.swap(c); }
MyClass c1, c2;
c1.swap(c2);
This is now an exception safe way of transferring c2's contents to c1. Another great reason to use a the PIMPL idiom is to preserve/maintain a stable ABI.
Well, here is PIMPL idiom: http://en.wikipedia.org/wiki/Opaque_pointer It is pretty clear what it does.
And Bridge Pattern is more involved - it does not just hold data. http://en.wikipedia.org/wiki/Bridge_pattern#C.2B.2B
Related
We have a library with that publishes an abstract base class:
(illustrative psudocode)
/include/reader_api.hpp
class ReaderApi
{
public:
static std::unique_ptr <ReaderApi> CreatePcapReader ();
virtual ~ReaderApi() = 0;
};
In the library implementation, there is a concrete implementation of ReaderApi that reads pcap files:
/lib/pcap_reader_api.cpp
class PcapReaderApi
:
public ReaderApi
{
public:
ReaderApi() {};
};
Client code is expected to instantiate one of these PcapReaderApi objects via the factory method:
std::unique_ptr <ReaderApi> reader = ReaderApi::CreatePcapReader ();
This feels gross to me on a couple of levels.
First, the factory method should be free, not a static member of ReaderApi. It was made a static member of ReaderApi to be explicit about the namespaces. I can see pros & cons either way. Feel free to comment on this, but it's not my main point of contention.
Second, my instinct tells me I should be using std::make_unique rather than calling a factory method at all. But since the actual object being made is an implementation detail, not part of the public headers, there's nothing for the client to make_unique.
The simplest solution, in terms of understandability and code maintenance, appears to be the solution I've already come up with above, unless there is a better solution that I'm not already aware of. Performance is a not a major consideration here since, because of the nature of this object, it will only be instantiate once, at startup-time.
With code clarity, understandability, and maintainability in mind, is there a better way to design the creation of these objects than I have here?
I have considered two alternatives that I'll go over below.
One alternative I've considered is passing in some kind of identifier to a generic Create function. The identifier would specify the kind of object the client wishes to construct. It would likely be an enum class, along these lines:
enum class DeviceType
{
PcapReader
};
std::unique_ptr <ReaderApi> CreateReaderDevice (DeviceType);
But I'm not sure I see the point of doing this versus just making the create function free and explicit:
std::unique_ptr <ReaderApi> CreatePcapReader ();
I also thought about specifying the DeviceType parameter in ReaderApi's constructor:
class ReaderApi
{
public:
ReaderApi (DeviceType type);
virtual ~ReaderApi() = 0;
};
This would enable the make_unique idiom:
std::unique_ptr <ReaderApi> reader = std::make_unique <ReaderApi> (DeviceType::PcapReader);
But this obviously would present a big problem -- you're actually trying to construct a ReaderApi, not a PcapReader. The obvious solution to this problem is to implement a virtual constructor idiom or use factory construction. But virtual construction seems over-engineered to me for this use.
To me, the two options to consider are your current approach, or a namespace level appropriately named free function. There doesn't seem to be a need for an enumerated factory unless there are details you aren't mentioned.
Using make_unique is exposing implementation details so I would definitely not suggest that approach.
class MyClassPrivate
{
//My members.
};
//and then
class MyClass {
private:
MyClassPrivate* const d;
};
What is the reason of using this 'pattern'? How it's correctly called?
This is called "Pointer to implementation" or "pimpl". See http://en.wikibooks.org/wiki/C++_Programming/Idioms#Pointer_To_Implementation_.28pImpl.29
When you use this pattern you would forward declare the implementation class, and declare the body elsewhere, i.e.:
// header
class MyClassPrivate;
class MyClass {
public:
MyClass();
~MyClass();
private:
MyClassPrivate* const d;
};
// cpp
class MyClassPrivate {
};
MyClass::MyClass() : d(new MyClassPrivate) {}
MyClass::~MyClass() { delete d; }
The advantage of doing this is that the implementation of MyClass is not exposed to other users of MyClass. If the implementation changes, the other users of MyClass does not need to be recompiled. Any header files that has to be included for members also need not be exposed, which improves compilation time.
The most usage is Pimlp idiom.
Why should the “PIMPL” idiom be used?
Pimpl idiom
The Pimpl
The Pimpl idiom describes a way for making your header files
impervious to change. You often hear advices like "Avoid change your
public interface!" So you can modify your private interface, but how
can you avoid recompilation when your header file defines the private
methods. This is what the Pimpl does – Reduce compilation damages when
your private interface changes[3].
From Here:
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 implementer.
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).
How to do it:
Put all the private member variables into a struct.
Put the struct definition in the .cpp file.
In the header file, put only the ForwardDeclaration of the struct.
In the class definition, declare a (smart) pointer to the struct as the only private member variable.
The constructors for the class need to create the struct.
The destructor of the class needs to destroy the struct (possibly implicitly due to use of a smart pointer).
The assignment operator and CopyConstructor need to copy the struct appropriately or else be disabled.
You can use this for the PIMPL idiom, when you want to separate interface from iplementation.
Many design patterns use a "pointer" to a private attribute as well, such as the Strategy Pattern. This patterns allows you to select a different algorithm at run-time.
Also, if you make the manipulation of your data adhere to the same interface, you can encapsulate the data in a Private Class, make this class a part of a hierarchy and switch between different data implementations during run time (or compile time for that matter :)).
A good example of this is a geometrical class that holds data on polygons. Each Polygon provides access to the points, you can also delete the Polygon edge and do various other topological operations. If you provide an abstract base class for the Polygon class with the methods such as deletePoint, addPoint, swapEdge, you can test different Polygon implementations.
You may define a polygon as a list of Point types directly, and store the points in different contaienrs (list or vector). The Polygon class may be defined via indirect addressing, where the polygon is actually a list of IDs to the list of points (I am talking about lists in the general sense). This way, you can test different algorithms of the PolygonGeometry class and see how they work with differtn Polygon implementations.
There is a design principle behind this: Prefer Composition to Inheritance. Whenever you are using Composition and you are relying on the type to be deterimined at run-time, you will have a private attribute pointer.
I'm implementing several classes using the pimpl idiom and am coming across some design issues.
Firstly, I've always seen pimpl done like this
class Object
{
public:
Visible();
~Visible();
.. etc ..
private:
class ObjectImpl *_pimpl;
};
I have several classes which use this approach and my problem is that several of these classes need access to each others implementation details but the _pimpl pointer is delcared private.
Can anyone see the downside of declaring the _pimpl public. Obviously, if it's public then someone may accidentally (or deliberately) reassign it. (I'm ignoring the fact that "private" could be #defined as "public" and grant access anyway. If you do this then you deserve what you get).
I appreciate that my design may be flawed and would welcome any comments along those lines also.
I'm really loathe to use friends and am not sure they'll even help as you can't forward declare the Object::ObjectImpl without fully defining Object.
i.e.
...
private:
class ObjectImpl *_pimpl;
friend class OtherObject::OtherObjectImpl; // this needs a fully qualified OtherObject
};
Thx
Mark.
* UPDATE - More detail **
I have two classes, one called Command, the other called Results. I have methods on Command which return a vector of Results.
Both Command and Results use the pimpl idiom. I want the interface to Results to be as small as possible.
class Command
{
public:
void getResults( std::vector< Results > & results );
void prepareResults( std::vector< Results > & results );
private:
class CommandImpl *_pimpl;
};
class Results
{
public:
class ResultsImpl;
Results( ResultsImpl * pimpl ) :
_pimpl( impl )
{
}
private
ResultsImpl *_pimpl;
};
Now in Command::getResults(). I inject the ResultsImpl into the Results. in Command::prepareResults() I need access to the ResultsImpl.
M.
I doubt there is a good reason to make the implementation public: you can always expose the implementation's functionality using public methods:
class Object
{
public:
Object();
~Object();
int GetImplementationDetail();
private:
std::unique_ptr< ObjectImpl > _pimpl;
};
int Object::GetImplementationDetail()
{
return pimpl->GetImplementationDetail();
}
Apart from that a class should be responsible for one thing, one thing only, and should have the bare minimum of dependencies to other classes; if you think other classes should be able to access your Object's pimpl then your design is likely flawed.
edit following the author's update: although your example is still rather vague (or at least I cannot tell the full intent of it), you seem to be misinterpreting the idiom and now try to apply it to a case where it is not usefull. As others pointed out, the 'P' stands for private. Your results class doesn't have much private implementation since all of it is public. So either try to use what I mention above and do not 'inject' anything, or just get rid of the pimpl all together and use just the Result class. If your Result's class interface should be so small that it's nothing but a pointer to another class it doesn't seem to be of much use in this case.
Why exactly do your classes depend on details of each other? You may re-think your design. Classes should depend on abstractions.
If you really deem your design proper, nothing stops you from providing a "source-file-private" header, like:
include/
foo.h
src/
foo.impl.h
foo.c
bar.c
and then #include foo.impl.h in both foo.c and bar.c
foo.c:
#include "foo.impl.h"
...
bar.c:
#include "foo.impl.h"
...
But again: Generally,
Dependency Inversion Principle:
A. High Level Modules should not depend upon low level modules. Both should depend upon abstractions.
B. Abstractions should not depend upon details. Details should depend upon abstractions.
Also make very sure to check out SOLID and GRASP, especially the point about loose coupling.
It is unnecessary to qualify the friend thusly.
If you just use friend class OtherObject, then the OtherObject class may access the necessary internals.
Personally my Pimpl are just a struct (bundle of data) and I leave the methods to operate on it in the original class.
Making the the data member _pimple public won't buy you anything as long as those other classes do not see the definition of its type ObjectImpl - which is the very thing Pimple set out to prevent.
What you can do instead is to add a private interface to your Object class which will allow befriended classes to do whatever they need to do with an Object.
Of course, the common disclaimers about friend being a tool that should be used as rarely as possible all apply.
d-pointers are heavily used in Qt, they are an implementation of pimpl idiom. I know advantages and disadvantages of pimpl idiom. But I have missed the advantages of d-pointers implementation. Here and here are the samples of d-pointers.
Isn't it easier to just use this?
class MyClassPrivate;
class MyClass {
// interface methods
private:
MyClassPrivate *pimpl_;
};
d-pointers are one implementation, among many, of the pimpl pattern. It is also one of the early implementations: "The name 'd-pointer' stems from Trolltech's Arnt Gulbrandsen, who first introduced the technique into Qt, making it one of the first C++ GUI libraries to maintain binary compatibility even between bigger release." Source
One advantage of using macros is the option of changing some implementation details of the pattern implementation in a central place at compile time. You could for example design your macros to leave you the option of switching to the fast pimpl implementation at a later time without changing tons of code (hopefully you won't need this if you are using pimpl :-)). Provided that you made no mistakes in your macro design/implementation...
However, I would personally recommend avoiding macros for your pimpl implementation as they are cryptic for any newcomer to your source tree. Macros create magical dialects that are often error-prone and not as meaningful as the original source code. They also come with all the problems associated with the C Pre Processor; it's unaware of the underlying language.
Personally I like to use what I call a d-reference. Instead of a pointer, you use a reference and you don't have to d-reference. 8-) It looks something like this:
// MyClass.h
class MyClass
{
public:
MyClass();
~MyClass();
// implementation methods
private:
class MyClassPrivate& d;
};
// MyClass.cpp
struct MyClassPrivate
{
int x;
};
MyClass::MyClass()
: d(*new MyClassPrivate)
{
}
MyClass::~MyClass()
{
delete &d;
}
// In methods use d.x
The set of macros for d-pointer pattern provides some sort convenience and consistencies. For example, Q_DECLARE_PRIVATE ensures that the pimpl private class for Foo is named as FooPrivate, that FooPrivate befriends Foo, and creates an nice inline function (both const and nonconst versions) called d_func(). The latter is used in Q_D macro, which basically creates a scoped/local variable d which points to the private class instance.
In short, you need not use Q_DECLARE_PRIVATE and other macros, but doing so will make the code shorter, cleaner, and consistent.
I think that d-pointers are really just a few handy macros for implementing the pimpl idiom. Just take a look at the definition of all these macros: Q_D, Q_Q, Q_DECLARE_PRIVATE, etc. They are just shortcuts for parts of pimpl. For example most of the time you want to keep the reference to the original class in the private class. There are Q_Q and Q_DECLARE_PUBLIC for this. After all, using the macros forces all the team to have a uniform implementation of pimpl. Otherwise some people would call the private pointer d, others pimpl_, imagine this mess.
File a.hpp:
class a;
typedef boost::shared_ptr<a> aPtr
class a{
public:
static aPtr CreateImp();
virtual void Foo() = 0 ;
....
};
File aImp.hpp:
class aImp : public a{
virtual void Foo();
};
File aImp.cpp:
aPtr a::CreateImp()
{
return aPtr(new aImp());
}
void aImp::Foo(){}
The client must use CreateImp to get pointer to a, and can't use a other ways.
What do you think about this implementation?
What do you think about this kind of implementation?
This looks like a normal implementation if the Factory Method design pattern. The return of boost::shared_ptr just makes life of the programmer using this API easier in terms of memory management and exception safety and guards against simple mistakes like calling the function and ignoring the return value.
Edit:
If this is the only implementation of the base class, then it might be that the author was aiming for pimpl idiom to hide the implementation details and/or reduce compile-time dependencies.
If the intention is using the PIMPL idiom, then it is not the most idiomatic way. Inheritance is the second strongest coupling relationship in C++ and should be avoided if other solutions are available (i.e. composition).
Now, there might be other requirements that force the use of dynamic allocation, and/or the use of an specific type of smart pointer, but with the information you have presented I would implement the PIMPL idiom in the common way:
// .h
class a {
public:
~a(); // implement it in .cpp where a::impl is defined
void op();
private:
class impl;
std::auto_ptr<impl> pimpl;
};
// .cpp
class a::impl {
public:
void op();
};
a::~a() {}
void a::op() { pimpl->op(); }
The only (dis)advantage of using inheritance is that the runtime dispatch mechanism will call the implementation method for you, and you will not be required to implement the forwarding calls (a::op() in the example). On the other hand, you are paying the cost of the virtual dispatch mechanism in each and every operation, and limiting the use of your class to the heap (you cannot create an instance of a in the stack, you must call the factory function to create the object dynamically).
On the use of shared_ptr in the interface, I would try to avoid it (leave freedom of choice to your users) if possible. In this particular case, it seems as if the object is not really shared (the creator function creates an instance and returns a pointer, forgetting about it), so it would be better to have a smart pointer that allows for transfer of ownership (either std::auto_ptr, or the newer unique_ptr could do the trick), since the use of shared_ptr imposes that decision to your users.
(NOTE: removed it as the comment makes it useless)
Looks like good encapsulation, although I don't actually see anything preventing a from being used otherwise. (For example, private constructor and friend class aImp).
No compile unit using class a will have any knowledge of the implementation details except for aImp.cpp itself. So changes to aImp.hpp won't induce recompiles across the project. This both speeds recompilation and prevents coupling, it's helps maintainability a lot.
OTOH, anything implemented in aImp.hpp now can't be inlined, so run-time performance may suffer some, unless your compiler has something akin to Visual C++ "Link-Time Code Generation" (which pretty much undoes any gain to build speed from encapsulation).
As far as the smart pointer is concerned, this depends on project coding standards (whether boost pointers are used everywhere, etc).