Design of Generic Singleton Wrapper class - c++

We are in the process of deprecating ACE libraries in our project which consists of around 120 binaries and in many of binaries we have used ACE_Singleton.Since after deprecating we will not have this class so we are thinking of writing our own generic singleton in our shared library that is common across all these binaries and one of the goals that we want to achieve is if somebody inherit from this class (using CRTP) say Logger and even when Logger constructor is public then also we cannot create two logger object.
To illustrate let's assume my singleton class name is GenericSingleton and my client class is logger then following code should throw error :
class Logger:public GenericSingleton<Logger>
{
public:
Logger()
{
}
};
int main()
{
Logger obj;// first instance no issue
Logger obj1; // second instance is problem as it is inherited from singleton
}
So can somebody suggest me how GenericSingleton should be designed so that while creating second object i should get compiletime error ?
In short is there a way that if my derived class doesn't have private constructor,destructor copy constructor etc. then it can be checked at compiletime using static_assert ?

There's no way for a constructor to know at compile time where or how many times it will be called; constructors are just functions, and functions don't know anything about their contexts. Consider that any static_asserts will be evaluated when the class is compiled, but this can (and almost certainly will!) happen in an entirely different translation unit from code that actually instantiates the class.
In any case, it seems unlikely that this would be helpful, because you must have some way to access singletons throughout your codebase.
Additionally, it's unclear why you want to permit your singletons to have public constructors. If you want to enforce singleton behavior at compile time for a completely arbitrary class just by adding an inheritance declaration, you're out of luck; arbitrary classes can be, well, arbitrarily constructed.
Since you're transitioning from the ACE singleton, I suggest you use a similar API; note that the ACE singleton documentation recommends making your singleton constructors private.
If, however, you just want some way to force your client to write a constructor that can't (easily) be called improperly, you can do something like this:
template <typename T>
class SingletonBase {
protected: class P { friend class SingletonBase<T>; P() = default; };
public:
SingletonBase(P) {}
static T& Instance() {
static T instance { P {} };
return instance;
}
};
(You will also need to delete the base class's copy and move constructors. Here is a working example use case. Note that declaring P's constructor =default does not prevent the singleton class from default-initializing instances of P. )
Now, because the base class constructor takes an argument of type P, the singleton class implementation must pass a P to its parent class constructor. But since the constructor for P is private, the singleton class won't be able to construct an instance of P except by copy or move construction, so its constructor must take an instance of P. But since P itself is protected, only the singleton class and the parent class can actually use it, so effectively the only possible call to the child's constructor must be in the Instance method.
Note that you do not need to explicitly declare and define the singleton-class's constructor, which would be ugly because of the need to use SingletonBase<Singleton>::P. You can simply expose the constructor with a using declaration:
using BASE = SingletonBase<Myclass>;
using BASE::SingletonBase;

You need to make sure that instances of Logger cannot be created outside the function that creates the sole instance of Logger.
Here's a simple implementation.
template <typename T> class GenericSingleton {
public:
static T& instance() {
static T instance_;
return instance_;
}
};
class Logger: public GenericSingleton<Logger>
{
// Make sure that the base class can create the sole instance of
// this class.
friend GenericSingleton<Logger>;
private:
// Makes sure that you cannot create objects of the class
// outside GenericSingleton<Logger>
~Logger() {}
public:
void foo() {}
};
int main()
{
// OK. Call foo() on the only instance of the class.
Logger::instance().foo();
// Not OK.
Logger obj1;
}

My advice would be to separate concerns. There is the concept of a service (such as a logger) and the service may or may not be a singleton. But this is an implementation detail, and therefore a separate concern. The consumer of the service ought to be agnostic of it.
Now, later in the lifecycle of the project, when you realise that singletons were a terrible idea, you can refactor the singleton without having to refactor any code that depends on it.
e.g.:
template<class Impl>
struct implements_singleton
{
using impl_type = Impl;
static impl_type& get_impl()
{
static impl_type _{};
return _;
}
};
struct logger_impl
{
void log_line(std::string const& s)
{
std::clog << s << std::endl;
}
};
struct logger
: private implements_singleton<logger_impl>
{
void log_line(std::string const& s) {
get_impl().log_line(s);
}
};
void do_something(logger& l)
{
l.log_line("c");
}
int main()
{
logger a;
logger b;
a.log_line("a");
b.log_line("b"); // behind the scenes this is the same logger
// but the user need not care
do_something(a);
}

Related

I wonder if I can allocate a class to a particular member data and create an instance of that class

I want to know whether it is possible or not.
I have a class in one project.
class A { ...
void CreateInternal(void);
B* m_pData;
... }
void A::CreateInternal(void)
{
m_pData= new B;
}
and in other project, i add C class and want to make it in A::CreateInernal(void) like this...
void A::CreateInternal(void)
{
m_pData = new C; // ex) B is base class of C
}
Of course, i can make Class A to template class, however, i do not want it. I want to use it last. ( Suppose that dependency or other build error is free )
typename<class T>
class A { ...
void CreateInternal(void);
T* m_pData
... }
void A<T>::CreateInternal(void)
{
m_pData = new T;
}
I just want to register Class B or Class C in Class A.
Is it possible??
Thank you for your reply!
As denoted in the comments:
You don't want to make A a template class.
You the classes you want to create instances of share a common base class, which is the type of the member pointer as well (precondition for the following!).
So you can make createInternal a template function instead:
template <typename T>
void A::createInternal()
// ^^^ A still is a normal class!
{
m_data = new T();
// (will fail if T is a different type NOT inheriting
// from the base class in question)
}
Side note: Normally, if template functions are provided inside classes, you would have to implement them in the header file (typically at least, there are ways around...), if createInstance is private, though, and you don't call it from public inline functions, you can safely implement it in the source file as well as this file will be the only location the template ever is used.
You can even go a step further and allow to call all possible constructors by use of a variadic template:
template <typename T, typename ... TT>
void A::createInternal(TT&& ... tt)
{
m_data = new T(std::forward(tt)...);
// (will fail, if there is no matching constructor
// for the arguments provided)
}
OK, you now have to specify which instance you want to create:
void A::f()
{
createInternal<B>();
createInternal<C>();
}
I assume this being acceptable as you need to be able to tell somehow which type you actually want to create.
The alternative would be different functions for different classes (createInternalB, createInternalC), but that certainly is less elegant.
Side note:
Is it possible??
Even if your classes did not share a common base class, you still could store your objects created in a std::variant or, if you happen to compile pre-C++11, even in a union (but you need to take care yourself about which type actually is stored – in this respect, std::variant is just much safer, so prefer it whenever possible).
Update on new comments:
If you want to be able to create arbitrary objects within A without having to know which one actually is created, now offering two further alternatives:
In first variant you could make createInternal virtual in A (possibly even pure virtual) and then override in derived classes to provide the objects suiting your needs.
In second variant you provide an instance of some object provider class; assuming D is the base class of both B : public D and A : public D, so then the solution might look similar to this:
class A
{
public:
class ObjectProvider
{
public:
virtual ~ObjectProvider() = default;
public: virtual D* createInstance() = 0;
};
template <typename T>
class TheObjectProvider : public ObjectProvider
{
public:
D* createInstance() override
{
return new T();
}
};
A(std::unique_ptr<ObjectProvider> p)
: objectProvider(std::move(p))
{ }
private:
std::unique_ptr<ObjectProvider> objectProvider;
std::unique_ptr<D> m_data;
void createInternal()
{
m_data = objectProvider->createInstance();
}
};
Usage:
A ab(std::make_unique<A::ObjectProvider<B>());
// your own custom object provider:
class OP : public A::ObjectProvider
{
public:
C* createInstance() override { return new C(); }
};
A ac(std::make_unique<OP>());
The std::unique_ptr as parameter (although in general, it is not recommended to use smart pointers for) now has an important function: It indicates that the class will take ownership of the object passed, i. e. is a sink in Herb Sutter's wording – see his GotW91).
If you have a most commonly used data type (e. g. B), you could provide an overloaded default constructor providing an object provider for this type (or possibly the base type D, if not being abstract).

make_unique doesn't compile for creating a singleton instance

All,
I am using C++14 and am making a more-or-less standard Singleton. I am using the latest Visual Studio 2017. This code works:
#include <memory>
class A
{
public:
static A& getInstance()
{
if (instance == nullptr)
instance = std::unique_ptr<A>(new A());
return *instance;
}
private:
A() {}
static std::unique_ptr<A> instance;
};
std::unique_ptr<A> A::instance = nullptr;
However, when I change the creation of the singleton instance to this:
instance = std::make_unique<A>();
I get a compilation error that I am trying to access a private member:
Error C2248 'A::A': cannot access private member declared in class 'A'
c:\program files (x86)\microsoft visual studio\2017\professional\vc\tools\msvc\14.14.26428\include\memory 2510
This feels like a bug to me, as the two forms should be identical in function? Thoughts?
The purpose of std::unique_ptr<> is to control the lifetime of the object pointed to. You may pass a std::unique_ptr<> around, but that will also transfer ownership of the object pointed to. This concept does not match very well with the concept of a singleton. There is only one place that is ever allowed to create (or delete) the singleton. You don't really need a std::unique_ptr<>for that. As already said in the comments, there are simpler ways for that. I would prefer #Praetorian's suggestion:
static A& getInstance()
{
static A instance;
return instance;
}
The reason why you can't use std::make_unique<>() to instantiate your class is that the constructor is private. To access it, you need the accessing function to be a friend. Have a look at How to make std::make_unique a friend of my class for that. Another solution is to provide a public constructor requiring a private type as argument, as described int this solution.
instance = std::make_unique<A>();
this creates the A within the function make_unique. But the ctor you want to call is private.
private:
struct ctor_permission_t{
explicit ctor_permission_t(int){};
};
public:
explicit A(ctor_permission_t):A(){}
};
then
instance = std::make_unique<A>(ctor_permission_t{0});
The ctor_permission_t acts as a token giving its possessor the right to construct an A. We pass this to make_unique.
The explicit int ctor in ctor_permission_t makes it impossible to create it without naming the type, and only within instances and friends of A can name it because it is private. This makes it difficult to bypass this permission token.
To sum up the others answers' and fix some flaws in them:
You can make a private structure with a private constructor which is a friend with your class. Then make your class constructor public but with an additional argument of that private structure.
Also its better to use static function witch return a reference instead of the bare static variable.
#include <memory>
class A
{
struct Private
{
friend A;
private:
explicit Private() = default;
};
public:
static A * getInstance()
{
if (!instance())
instance() = std::make_unique<A>(Private());
return instance();
}
A(Private) {};
private:
static std::unique_ptr<A> & instance()
{
static std::unique_ptr<A> inst;
return inst;
}
};
Or if you really dont need any special configurations which requires using a pointer and heap allocation (like initializing the instance in a special thread or ...) :
class A
{
public:
static A & getInstance()
{
static A instance;
return instance;
}
private:
A() = default;
};

C++ Singleton inheritance issue

I am trying to implement an easy inherited Singleton pattern for my child classes.
Therefore, I am implementing a parent class and, as I want to make things as easy as possible for others to create a new Singleton child class, I need to handle inside the father class constructor all the operations needed for the Singleton implementation for the child classes.
#include <vector>
#include <typeinfo>
#include <iostream>
class Father
{
protected:
Father()
{
for(auto & instance : Father::singletonInstances)
if(typeid(instance) == typeid(this)) // typeid(this) will always be "Father", which is actually the issue
{
// Singleton instance already exists for this class
* this = instance;
std::cout<<"An instance of the given class is already active\n";
return;
}
std::cout<<"Constructed\n";
// Otherwise, mark this as the Singleton instance for this class
Father::singletonInstances.emplace_back(this);
}
public:
Father operator=(Father * inputObj) { return * inputObj; }
private:
static std::vector<Father *> singletonInstances;
};
std::vector<Father *> Father::singletonInstances;
class Child : protected Father
{
public:
Child() : Father() {}
};
class Child2 : protected Father
{
public:
Child2() : Father() {}
};
int main()
{
new Child();
new Child2();
return 0;
}
Output :
Constructed
An instance of the given class is already active
So, to make things clear again :
- The issue is that typeid(this) is always "Father" inside the constructor
- new Child(); new Child2(); should be allowed
- new Child(); new Child(); should not be allowed
- No modifications should be made to the child classes
I know my implementation of the Singleton could look rather strange. I am open to new ideas.
I was able to implement these ideas in JScript, yet in C++ I cannot seem to find a way to make it work.
When a class with inheritance is created the base class constructor is called first, after that the child classes upward in the hierarchy. This means that in the constructor of Father, Child/Child2 is not yet constructed.
Trying to use the object before it's constructed would probably result in Undefined Behavior. C++ tries to protect you from this. Read for example the FAQ Lite. This is not the exact same thing, but related and reading this should give you an idea why typeid would say that the object is a Father.
On cppreference we can read
If typeid is used on an object under construction or destruction (in a destructor or in a constructor, including constructor's initializer list or default member initializers), then the std::type_info object referred to by this typeid represents the class that is being constructed or destroyed even if it is not the most-derived class.
I have seen several ways to implement singletons, the most modern seems to be to return a reference to a static function object. Here is one idea.
#include <iostream>
template <typename T>
T& Singleton() {
static T single;
return single;
}
class Foo {
private:
Foo() {
std::cout << "Constructed" << std::endl;
}
friend Foo& Singleton<Foo>();
public:
void print() {
std::cout << "Foo" << std::endl;
}
};
int main() {
//Foo f; not allowed
Singleton<Foo>().print();
Singleton<Foo>().print();
}
This requires every singleton instance to have a private constructor and to friend the template instantiation. Only the Singleton function will be allowed to construct a Foo and it will only construct 1 copy ever. It's also thread safe and you don't need to worry about clean-up. Other approaches can be found if you google around.

Non-Virtual Polymorphism in C++

I have developed the following code in an attempt to implement non-virtual polymorphism:
#include <functional>
#include <iostream>
namespace{
using std::function;
class base {
protected:
using signiture =void(void);
using func_t = function<signiture>;
~base(){}
public:
func_t bar;//std::function object to a function of type "signature"
};
}
template <typename implementation>
class foo:public base {
public:
foo(implementation* instance){
bar = func_t(std::bind(&implementation::bar_implementation,instance));
//binds a function of name "bar_implementation" from class implementation to the std::function object
//binds to object "instance"
}
};
typedef base foo_base;
class testcase:public foo<testcase> {
public:
friend class foo;//allows implementations to be protected or private
testcase():foo(this){}//sends instance to the constructor of the base class in order to enable binding
protected:
void bar_implementation(void){
std::cout<<"Hello"<<std::endl;
}
};
class testcase2:public foo<testcase2> {
public:
friend class foo;//allows implementations to be protected or private
testcase2():foo(this){}
protected:
void bar_implementation(void){
std::cout<<"World!"<<std::endl;
}
};
int main(int argc, const char * argv[]) {
testcase t;
testcase2 t2;
foo_base* b = &t;
foo_base* b2 = &t2;
b->bar();
b2->bar();
return 0;
}
In reality this code is spread out over a few files...
I would like to know if anything in my code can be considered bad-practice,undefined behavior or otherwise undesirable in some manor?
A Live Example
Any thoughts on this pattern as a replacement for virtual inheritance and the design are appreciated.
Let me know if i can clarify anything.
EDIT:
I am asking this question as an attempt to determine if there are any reasons why a design like this would be a suitable way to implement non virtual polymorphism and if it is not, why is that?
Your code is an interesting approach. It's a nice proof of concept but it has a major flaw: it doesn't manage inheritance consistently !
The problem : class inheritance
Suppose I want to create a class testcase22 which inherits from testcase2, but has its own implementation of bar().
Alternative 1: if I define it naively by inheriting from testcase2, it will use the bar_implementation of testcase2:
class testcase22:public testcase2 {
public:
testcase22() {} // naive contructor
protected:
void bar_implementation(void){ // will not be used
std::cout<<"Great!"<<std::endl;
}
};
Alternative 2: If I try to use your constructor pattern, it won't work because of a compiling error. Because the type deduction will use foo<testcase2>, which is not a direct base class of testcase22 and can hence not be used in the mem-initializer list:
class testcase22:public testcase2 {
public:
friend class foo;//allows implementations to be protected or private
testcase22():foo(this){} // !!!!! causes compile error
protected:
void bar_implementation(void){
std::cout<<"Great!"<<std::endl;
}
};
Alternative 3: if I'd use foo explicitly, it would not work because foo os not either a valid base type initializer.
Alternative 4: if I'd try to use multiple inheritance, I'd be confronted to ambiguous base class
class testcase22:public testcase2, public foo<testcase22> {
public:
friend class foo;//allows implementations to be protected or private
testcase22():foo(this){}
protected:
void bar_implementation(void){
std::cout<<"Great!"<<std::endl;
}
};
This could be solved by defining foo inheriting virtually from base:
class foo:public virtual base { ... };
Then it would compile, but it still would use the bar_implementation of testcase2 instead of that from testcase22. By the way, even if it would have worked, the virtual base would prevent possibility of using multiple inheritance with your class family.
Conclusion
Your nice construct works, but only with a single level of simple inheritance.
This is a major constraint. Especially when considering that the benefit of polymorphism is to manage natural hierarchies making best use of the inheritance relationships.
Your pattern is also relatively complex to use in comparison with easy to use virtual functions. What will your code look like with several polymorphic functions, some of them even overloaded ?
The goals you intend to achieve with your pattern is not clear, but honestly, I wouldn't go for this approach for real life projects that have to be maintained over several years. But this is my own subjective opinion of course.

Global Constructors with CRTP

I'd like to allow a class to inherit from a base CRTP class that causes a global constructor to be created and run before main() begins. The idea is to use this to register a type in some map to be looked up later. It seems that this only works if I've actually instantiated a member of the Derived class and used the Base class.
#include <iostream>
class Foo {
public:
Foo() { std::cout << "Foo" << std::endl; }
};
template <typename T>
class Bar {
private:
static Foo foo_;
};
class Test : public Bar<Test> {
};
int main() {
return 0;
}
class Test inherits from Bar<Test> which has a static member variable of type Foo. Unfortunately, Foo's constructor is not invoked. I'd like to be able to cause a global constructor to be run when a class instantiates a template using CRTP without needing to actually create an instance of that class. I'd be happy with implementation dependent solutions too.
There is no way besides SomeClass instance in a translation unit to have a global class instance.
With a template and a static member, you might (or might not) end up with globals in multiple translation unit.
If you declare a class with static fields, it doesn't matter is it template-driven or not - static members would not be instantiated unless you create an instance of such class. And be aware - time of the static members instantiation is quite tricky thing, especially if you have multiple libraries involved.