When implementing singletons in c++, I see two ways to store implementation data :
(A) put all implementation data in the private section and implement class as usual
(B) "pimpl idiom for singletons" : hide implementation data by placing it to the 'Impl' structure, which can be defined in the implementation file. Private section contains only a reference to the implementation structure.
Here is a concept code to clarify what I mean by (A) and (B) implementation options :
(A) SingletonClassMembers.hpp :
// a lot of includes required by private section
#include "HelperClass1.hpp"
#include "HelperClass2.hpp"
// some includes required by public section
// ...
class SingletonClassMembers {
public:
static SingletonClassMembers& getInstance();
// public methods
private:
SingletonClassMembers ();
~SingletonClassMembers();
SingletonClassMembers (const SingletonClassMembers&); //not implemented
SingletonClassMembers& operator=(const SingletonClassMembers&); //not implemented
HelperClass1 mMember1;
HelperClass2 mMember2; //and so on
(A) SingletonClassMembers.cpp :
#include "SingletonClassMembers.hpp"
SingletonClassMembers& getInstance() {
static SingletonClassMembers sImpl;
return sImpl;
}
(B) SingletonHiddenImpl.hpp :
// some includes required by public section
// ...
class SingletonHiddenImpl {
public:
static SingletonHiddenImpl& getInstance();
// public methods
private:
SingletonHiddenImpl ();
~SingletonHiddenImpl ();
SingletonHiddenImpl (const SingletonHiddenImpl&); //not implemented
SingletonHiddenImpl& operator=(const SingletonHiddenImpl&); //not implemented
struct Impl;
Impl& mImpl;
};
(B) SingletonHiddenImpl.cpp :
#include "SingletonHiddenImpl.hpp"
#include "HelperClass1.hpp"
#include "HelperClass2.hpp"
struct SingletonHiddenImpl::Impl {
HelperClass1 member1;
HelperClass2 member2;
};
static inline SingletonHiddenImpl::Impl& getImpl () {
static Impl sImpl;
return sImpl;
}
SingletonHiddenImpl::SingletonHiddenImpl ()
: mImpl (getImpl())
{
}
So, using (B) approach, you can hide implementation details better and (unlike pimpl idiom for ordinary classes) there`s no performance loss. I can`t imagine conditions where (A) approach would be more appropriate
The question is, what are the advantages of storing implementation data as class members (A) ?
Thank you
Using case A has following benefits:
You reduce dependency between classes SingletonClassMembers and SingletonHiddenImpl.
You don't need to create configurator pattern in class SingletonClassMembers if you trying avoid restriction on (1) by dependency injection
This case is weak, but anyway: it is simple to maintenance single class
In multithreading environment you will need to support both class synchronization mechanism, while in single class only single locks is needed.
As you only have one instance of your singleton, you can actually move your helpers into the implementation class as "static" there without requiring them to be private inside the header. Of course you don't want to initialise them until you start your class so you would use some kind of smart-pointer, could be auto_ptr here or boost::scoped_ptr, or a pointer with boost::once initialisation (more thread-safe) with deletes in your singleton's destructor.
You can call this model C and probably has the best of both worlds as you completely hide your implementation.
As is the case with any singleton, you need to be extra careful not to throw in your constructor.
When considering efficiency with pimpl, it is not the heap that causes overhead, but the indirection (done by delegation). This delegation typically isn't optimized out (at least not at the time I was considering this ;-)), so there is not a big gain apart from the startup (1 time) penalty for creating the impl. (BTW, I didn't see any delegation functions in your example)
So I don't see that much difference in using pimpl in normal classes or in singletons. I think in both case, using pimpl for classes with limited interface and heavy implementation, it makes sense.
Related
I have an API implemementation / design question to ask. I need to design a modern, usable DLL API, but I am unsure which approach is best and why. I'm not even sure if what I have below could be considered either!
My implementation of the classes needs to be abstracted from the client, but the client also needs to be able to extend and define additional (supported) classes as needed. Many of the internal classes of the library will need references to these external components, necessating the use of pure virtual classes or polymorphism.
I'm not too worried about GNU/Clang compatability - that may come later (as in much later or possibly never) but the primary need is in the ABI layers of MSVC 15/17.
The two ways I can see to implement this is to either use to use a Pimpl idiom or an external Factory method. I'm not a big fan of either (PIMPL adds to code complexity and maintainability, Factory abstracts class creation) so a well thought out third option is a possibility if viable.
For the sake of the simplicity in this post, I've put the "implementations" in the headers below, but they would in their own respective CPPs. I've also cut out any implied constructors, destructors or includes.
I'll define two pure virtual classes here for the meantime
//! IFoo.h
class IFoo
{
virtual void someAction() noexcept = 0;
}
//! IBar.h
class IBar
{
public:
virtual void Foo(IFoo& other) noexcept = 0;
};
Edit, I'll put this here too:
//! BarImpl.h (Internal)
class BarImpl : public IBar
{
public:
virtual void Foo(IFoo& foo) noexcept
{
foo.someAction();
}
};
First up, we have the PIMPL approach
//! Bar.h (External)
class API_EXPORT Bar : public IBar
{
private:
BarImpl* impl;
public:
virtual void Foo(IFoo& foo) noexcept
{
impl->Foo(foo);
}
};
Ideally, the client code therefore looks alittle something like this:
//! client_code.cpp
class CustomFoo : public IFoo;
int
main(int argc, char** argv)
{
auto foo = CustomFoo();
auto bar = Bar();
bar.Foo(foo); // do a barrel roll
}
Secondly, we have a Factory approach
//! BarFactory.h (External)
class API_EXPORT BarFactory
{
private:
BarImpl impl;
public:
virtual IBar& Allocate() noexcept
{
return impl; // For simplicity
}
}
The resulting client code looking something like:
//! client_code.cpp
class CustomFoo : public IFoo;
int
main(int argc, char** argv)
{
auto foo = CustomFoo();
auto barfactory = BarFactory();
IBar& bar = barfactory.Allocate();
bar.Foo(foo); // do a barrel roll
}
In my eyes, both approaches have their own merits. The PIMPL method, although double abstracted and possibly slower due to all the virtualisation, brings a humble simplicity to the client code. The factory avoids this but necessitates a seperate object creation / management class. As these are external functions, I don't think I can easily get away with templating these functions as you might expect to with an internal class, so all this extra code will have to be written either way.
Both methods seem to ensure that the interface remains stable between versions - ensuring binary compatibility between future minor releases.
Would anyone be able to lend a hand to the conundrum I have created for myself above? It would be much appreciated!
Many Thanks,
Chris
I need to define a singleton class in C++ that is implemented separately across different platforms. (e.g. macOS, Windows, Linux, etc.) In case it matters, this is for a Qt application and the singleton will be inheriting from QObject.
I could do this simply using some preprocessor directives and including totally separate implementations, like so:
// Singleton.h
#include <QtGlobal>
#if defined Q_OS_WIN
#include "Singleton_win.h"
#elif defined Q_OS_MAC
#include "Singleton_mac.h"
#elif ... etc ...
#endif
However, for my own planning and sanity I'd love it if there was a way I could define what actual methods need to be implemented across all platforms so that the different implementations can stay at least partially synchronized.
If I were programming in a language with interfaces, I would handle this just by defining an interface and having each platform-specific version of the singleton implement it.
However, this is C++, and the closest I have to an interface is an abstract base class. But using an abstract base class is troublesome. I need a static method on whatever the singleton is for getting the global instance of that singleton, and of course C++ doesn't allow abstract static methods. I can't use a templated static method that returns the right implementation of the singleton because everywhere else in my code that uses the singleton doesn't and shouldn't know which implementation it's going to use.
Lastly, I'd really like to avoid any patterns that involve an excessive amount of boilerplate code. One such pattern I feel could be used to create this Singleton but qualifies as involving excessive boilerplate is the PImpl pattern, because it would require me doing something like this:
// Singleton.h
class Singleton {
public:
Singleton();
~Singleton();
static Singleton * shared() { static Singleton s; return &s; };
void publicMethodA();
void publicMethodB();
// etc.
protected:
class impl;
impl *p;
}
// Singleton.cpp
class Singleton::impl {
public:
void publicMethodA();
void publicMethodB();
// etc.
}
void Singleton::impl::publicMethodA() {
// actual publicMethodA implementation here
}
void Singleton::impl::publicMethodB() {
// actual publicMethodB implementation here
}
// further public methods implemented here
// Singleton constructors and destructors implemented here
void Singleton::publicMethodA() {
impl->publicMethodA();
}
void Singleton::publicMethodB() {
impl->publicMethodB();
}
// further boilerplate for Singleton's public methods implemented here
Basically my gripe is that for every public method on Singleton that I write, I have to add a method that calls through to another method with an identical signature on Singleton::impl. This is just my personal preference, but I can't stand boilerplate code like that! I'd really like to avoid it.
Furthermore, once we consider that this is going to be a QObject-inherited class with Qt signals, slots, and possibly properties, having an Singleton::impl will introduce further complexities because it's Singleton that needs to be emitting signals and receiving connections from other QObjects.
So given that, are there any patterns I can use that allow me to implement this singleton the way I'm looking to do?
I am developing a library. I have interface class that would be called from outside.
I have also an internal engine that should not be called from outside.
As I read here and there, I should hide the internal engine class and not even populate its header. Since I have the following structure:
interface.hpp:
#include "engine.hpp"
class interface{
private:
enigne eng;
};
interface.cpp:
#include "engine.hpp"
//code that uses member variables and functions from eninge
engine.hpp:
class engine{};
To solve the problem of populating "engine.hpp", I should change the code to:
interface.hpp:
class engine;
class interface{
private:
some_smart_pointer<enigne> eng_ptr;
};
interface.cpp:
#include "engine.hpp"
//code that uses member variables and functions from eninge
enigne.hpp:
class engine{};
This solved the problem. However, from now engine is allocated dynamically. All its member variables are in the free store.
I can not understand that I have to change my design and allocate engine on the free store for solving the problem of hiding implementation details. Is there a better solution?
P.S. I am not asking about why this solution works. I know it's about knowing the size of engine class is mandatory if I would leave it on stack. My question is about asking for a different design that may solve the problem.
EDIT:
Both interface and engine have member variables.
You're using the PIMPL idiom. The other way to hide implementation is to use interfaces, i.e. an abstract base class and a factory function:
interface.hpp:
class interface{
public:
virtual ~interface(){}
virtual void some_method() = 0;
};
// the factory function
static some_smart_pointer<interface> create();
interface.cpp:
#include "interface.hpp"
#include "engine.hpp"
class concrete : public interface{
public:
virtual void some_method() override { /* do something with engine */ }
private:
engine eng;
};
some_smart_pointer<interface> create(){ return new concrete; }
main.cpp
#include "interface.hpp"
int main()
{
auto interface = create();
interface->some_method();
return 0;
}
The drawback here is that you must allocate dynamically interface instead of engine.
More discussion about PIMPL and interfaces here and here
EDIT:
Based on STL containers and Howard Hinnant's stack allocator, a third way to avoid variables in the free store can be:
interface.hpp:
class interface{
public:
interface();
~interface();
// I disable copy here, but you can implement them
interface(const interface&) = delete;
interface& operator=(interface&) = delete;
private:
engine* eng;
};
interface.cpp:
#include "interface.hpp"
#include "engine.hpp"
#include "short_alloc.h"
#include <map>
namespace
{
std::map<
interface*,
engine,
std::default_order<interface*>,
// use a stack allocator of 200 bytes
short_alloc<std::pair<interface*, engine>, 200>
> engines;
}
interface::interface():
eng(&engines[this])
// operator[] implicitly creates an instance and returns a reference to it
// the pointer gets the address
{
}
interface::~interface()
{
// destroy the instance
engines.erase(this);
}
I can not understand that I have to change my design and allocate engine on the free store for solving the problem of hiding implementation details.
You seem to already have explained it yourself:
I know it's about knowing the size of engine class
Indeed. If the interface had a member of engine type, then it would necessarily need to know the size of that member - otherwise the size of interface itself couldn't be known. The size of an incomplete type can not be known. Defining the member type would solve that but conflicts with your desire to hide the implementation.
Is there a better solution?
There is no better solution. PIMPL with free store - which is the pattern that you currently use - is as good as it gets.
Technically, PIMPL doesn't require you to use the free store. You can store the object anywhere you like. You could use static storage. But that would limit the number of instances that you can have. You can even allocate a buffer of memory as a member of interface, but you need to hard code the size of such buffer and it must match the size (and alignment) of engine.
I would categorise both of these theoretical suggestions as kludges - the latter in particular. Static storage may be worth it if your profiling suggests that the overhead of that particular extra allocation is significant and forgoing PIMPL is not an option.
This is the standard solution for this problem: It is named the PIMPL (pointer to implementation) idiom. And as the name says, it always involves a pointer (or smart pointer) to the implementation class because
C++ simply doesn't allow this:
class engine;
class interface{
private:
enigne eng;
};
The typical solution to hide implementations and not force objects to be allocated on the heap is to put them in a detail namespace, and put the headers for those types in a detail subdirectory.
Note that some aspect of your implementation will be exposed as it will affect the ABI of your library. There's no solution that can give you both ABI insulation and avoiding allocating objects on the heap.
Chances are that you're best off using pimpl, as you describe.
What are the disadvantages of the following implementation of the pImpl idiom?
// widget.hpp
// Private implementation forward declaration
class WidgetPrivate;
// Public Interface
class Widget
{
private:
WidgetPrivate* mPrivate;
public:
Widget();
~Widget();
void SetWidth(int width);
};
// widget.cpp
#include <some_library.hpp>
// Private Implementation
class WidgetPrivate
{
private:
friend class Widget;
SomeInternalType mInternalType;
SetWidth(int width)
{
// Do something with some_library functions
}
};
// Public Interface Implementation
Widget::Widget()
{
mPrivate = new WidgetPrivate();
}
Widget::~Widget()
{
delete mPrivate;
}
void Widget::SetWidth(int width)
{
mPrivate->SetWidth(width);
}
I would prefer not to have seperate headers and sources for the private implementation part of the class because the code is essentially of the same class - should they not reside together then?
What alternatives to this version would be better?
First, let's address the question of whether the private variables should reside with the class declaration. The private part of a class declaration is part of the implementation details of that class, rather than the interface exposed by that class. Any outside "user" of that class (whether it is another class, another module, or another program in the case of an API) will care only about the public part of your class, since that is the only thing that it can use.
Putting all the private variables directly into the class in a private section might look like it puts all relevant information in the same place (in the class declaration), but it turns out that not only are private member variables not relevant information, it also creates unnecessary and unwanted dependencies between your class' clients and what amounts to be implementation details.
If, for some reason, you need to add or remove a private member variable, or if you need to change its type (e.g. from float to double), then you modified the header file which represents the public interface to your class, and any user of that class needs to be recompiled. If you were exporting that class in a library, you would also break binary compatibility since, among other things, you probably changed the size of the class (sizeof(Widget) will now return a different value). When using a pImpl, you avoid those artificial dependencies and those compatibility problems by keeping implementation details where they belong, which is out of sight of your clients.
As you have guessed, there is however a tradeoff, which might or might not be important depending on your specific situation. The first tradeoff is that the class will lose some of its const-correctness. Your compiler will let you modify the content of your private structure within a method that is declared const, whereas it would have raised an error if it would have been a private member variable.
struct TestPriv {
int a;
};
class Test {
public:
Test();
~Test();
void foobar() const;
private:
TestPriv *m_d;
int b;
};
Test::Test()
{
m_d = new TestPriv;
b = 0;
}
Test::~Test()
{
delete m_d;
}
void Test::foobar() const
{
m_d -> a = 5; // This is allowed even though the method is const
b = 6; // This will not compile (which is ok)
}
The second tradeoff is one of performance. For most applications, this will not be an issue. However, I have faced applications that would need to manipulate (create and delete) a very large number of small objects very frequently. In those rare extreme cases, the extra processing required to create an allocate an additional structure and to defer assignations will take a toll on your overall performance. Take note however that your average program certainly does not fall in that category, it is simply something that needs to be considered in some cases.
I do the same thing. It works fine for any simple application of the PImpl idiom. There is no strict rule that says that the private class has to be declared in its own header file and then defined in its own cpp file. When it is a private class (or set of functions) that is only relevant to the implementation of one particular cpp file, it makes sense to put that declaration + definition in the same cpp file. They make logical sense together.
What alternatives to this version would be better?
There is an alternative for when you need a more complex private implementation. For example, say you are using an external library which you don't want to expose in your headers (or want to make optional through conditional compilations), but that external library is complicated and requires that you write a bunch of wrapper classes or adaptors, and/or you might want to use that external library in similar way in different parts of your main project's implementation. Then, what you can do is create a separate folder for all that code. In that folder, you create headers and sources as you usually would (roughly 1 header == 1 class) and can use the external library at will (no PImpl'ing of anything). Then, the parts of your main project which need those facilities can simply include and use them only in the cpp files for implementation purposes. This is more or less the basic technique for any large wrappers (e.g., a renderer that wraps either OpenGL or Direct3D calls). In other words, it's PImpl on steroids.
In summary, if it's just for a single-serving use / wrapping of an external dependency, then the technique you showed is basically the way to go, i.e., keep it simple. But if the situation is more complicated, then you can apply the principle of PImpl (compilation firewall) but on a larger proportion (instead of a ext-lib-specific private class in a cpp file, you have a ext-lib-specific folder of source files and headers that you use only privately in the main parts of your library / project).
I think there is no big difference. You can choose more convenient alternative.
But I have some other suggestions:
Usually in PIMPL I place implementation class declaration inside interface class:
class Widget
{
private:
class WidgetPrivate;
...
};
This will prevent using of WidgetPrivate class outside of Widget class. So you dont need to declare Widget as friend of WidgetPrivate. And you can restrict access to implementation details of WidgetPrivate.
I recommend using of smart pointer. Change line:
WidgetPrivate* mPrivate;
to
std::unique_ptr<WidgetPrivate> mPrivate;
Using smart pointers you will not forget to delete member. And in case of exception thrown in constructor already created members will be always deleted.
My varian of PIMPL:
// widget.hpp
// Public Interface
class Widget
{
private:
// Private implementation forward declaration
class WidgetPrivate;
std::unique_ptr<WidgetPrivate> mPrivate;
public:
Widget();
~Widget();
void SetWidth(int width);
};
// widget.cpp
#include <some_library.hpp>
// Private Implementation
class Widget::WidgetPrivate
{
private:
SomeInternalType mInternalType;
public:
SetWidth(int width)
{
// Do something with some_library functions
}
};
// Public Interface Implementation
Widget::Widget()
{
mPrivate.reset(new WidgetPrivate());
}
Widget::~Widget()
{
}
void Widget::SetWidth(int width)
{
mPrivate->SetWidth(width);
}
I have a class in my library which I want to expose to the users. I don't want to expose the whole class as I might want to make a binary incompatible changes later. I am confused with which of the following ways would be best.
Case 1:
struct Impl1;
struct Handle1
{
// The definition will not be inline and will be defined in a C file
// Showing here for simplicity
void interface()
{
static_cast<Impl1*>(this)->interface();
}
}
struct Impl1 : public Handle1
{
void interface(){ /* Do ***actual*** work */ }
private:
int _data; // And other private data
};
Case 2:
struct Impl2
struct Handle2
{
// Constructor/destructor to manage impl
void interface() // Will not be inline as above.
{
_impl->interface();
}
private:
Impl2* _impl;
}
struct Impl2
{
void interface(){ /* Do ***actual*** work */ }
private:
int _data; // And other private data
};
The Handle class is only for exposing functionality. They will be created and managed only inside the library. Inheritance is just for abstracting implementation details. There won't be multiple/different impl classes. In terms of performance, I think both will be identical. Is it? I am thinking of going with the Case 1 approach. Are there any issues that needs to be taken care of?
Your second approach looks very much like the compilation firewall idiom (sometimes known as the PIMPL idiom).
The only difference is that in the compilation firewall idiom, the implementation class is usually (but not always) defined as a member. Don't forget the constructor
(which allocates the Impl) and the destructor (which frees it). Along with the copy constructor and assignment operator.
The first approach also works, but it will require factory functions to create the objects. When I've used it, I've simply made all of the functions in the Handle pure virtual, and let the client code call them directly.
In this case, since client code actually has pointers to your object (in the compilation firewall idiom, the only pointers are in the Handle class itself), and the client will have to worry about memory management; if no cycles are possible, this is one case where shared_ptr makes a lot of sense. (The factory function can return a
shared_ptr, for example, and client code may never see a raw pointer.)