-1

for my project I need to create singletons of a generic type. Those singletons manage the generic types in a std::map with ID to Object. Here is my used code:

template <typename tComponent>
class InternalComponent {
public:
static InternalComponent& getInstance() {
    static InternalComponent s_result;
    return s_result;
}

void add(const tComponent& component, int id) {
    m_components[id] = component;
}

void remove(int id) {
    std::lock_guard<std::mutex> lock(m_mutex);

    auto it = m_components.find(id);
    if (it == m_components.end()) {
        throw std::runtime_error("Component can't be found.");
    }

    m_components.erase(it, m_components.end());
}

void replace(const tComponent& component, int id) {
    auto it = m_components.find(id);
    if (it == m_components.end()) {
        throw std::runtime_error("Component can't be found.");
    }

    m_components[id] = component;
}

tComponent* get(int id) {
    return &m_components[id];
}

private:
    InternalComponent() {};
    InternalComponent(const InternalComponent&);
    InternalComponent & operator = (const InternalComponent &);

    std::mutex m_mutex;
    std::map<int, tComponent> m_components;
};

In order to delete all Components with a specific ID from each singleton, I have to keep track of each created instance of the singleton. At this point I'm stuck.

The first problem is the generic type which can't be saved to a vector. I would bypass this with an Baseclass and derive InternalComponent from it.

However I would still be unable to save the references to a vector.

Also I'm unsure how to check if the singleton is created for the first time, without using an if-statement in each getInstance call, to avoid duplicates entries in my list of created singletons.

My final question would be: How can I manage each created instance of an InternalComponent in a single list.

noCma
  • 34
  • 4

1 Answers1

0

I figured out how I can keep track of all my created template based singleton.

#include <iostream>
#include <vector>

class Base {
public:
    virtual void delete(int id) = 0;
};

std::vector<Base*> test;

template<typename T>
class S : public Base
{
public:
    void delete(int id) override {
        //delete the component
    };

    static S& getInstance()
    {
        static S    instance;
        return instance;
    }

private:
    S() {
        test.push_back(this);
    }; 
public:
    S(S const&) = delete;
    void operator=(S const&) = delete;
};


int main()
{
    S<int>::getInstance();
    S<char>::getInstance();
    S<char>::getInstance();

    for (auto s : test) {
        s->delete(666);
    }

    exit(0);
}

I use an abstract class to later store a template based class inside a vector. The class provides the functions which are later needed. The constructor only gets called once, which allows me to store the this pointer and avoiding uneeded checks.

noCma
  • 34
  • 4