Summary: How to create a singleton mixin in C ++? I am trying to avoid copying the same function get_instance(), private constructor, etc. But I canβt figure out how to do this mixin, because the static instance will be shared by everything that inherits from mixin.
It is easy to make each derived class single, but is there a way to do this without duplicating code? Thanks so much for your help, I'm at a standstill.
Code:
I am writing a program with a class Registryto search for objects by name.
#include <string>
#include <memory>
#include <map>
#include <string>
#include <assert.h>
template <typename T>
class Registry
{
private:
Registry() {}
protected:
std::map<std::string, std::shared_ptr<T> > name_to_object_ptr;
public:
static Registry<T> & get_instance()
{
static Registry<T> instance;
return instance;
}
void register_name(const std::string & name, T*obj_ptr)
{
assert( name_to_object_ptr.count(name) == 0 );
name_to_object_ptr[name] = std::shared_ptr<T>(obj_ptr);
}
const std::shared_ptr<T> & lookup_name(const std::string & name)
{
assert( name_to_object_ptr.count(name) > 0 );
return name_to_object_ptr[name];
}
int size() const
{
return name_to_object_ptr.size();
}
};
My Registryclass is singleton; it must be singleton (so that registered objects do not disappear).
class DerivedRegistryA : public Registry<int>
{
};
class DerivedRegistryB : public Registry<int>
{
};
int main()
{
DerivedRegistryA::get_instance().register_name(std::string("one"), new int(1));
std::cout << DerivedRegistryA::get_instance().size() << std::endl;
DerivedRegistryA::get_instance().register_name(std::string("two"), new int(2));
std::cout << DerivedRegistryA::get_instance().size() << std::endl;
DerivedRegistryA::get_instance().register_name(std::string("three"), new int(3));
std::cout << DerivedRegistryA::get_instance().size() << std::endl;
DerivedRegistryB::get_instance().register_name(std::string("four"), new int(4));
std::cout << DerivedRegistryB::get_instance().size() << std::endl;
return 0;
}
Conclusion:
1
2
3
4
Desired conclusion:
1
2
3
1