【问题标题】:Keep track of each created template based singelton跟踪每个创建的基于模板的单例
【发布时间】:2016-09-13 17:23:01
【问题描述】:

对于我的项目,我需要创建泛型类型的单例。 这些单例管理具有 ID 到 Object 的 std::map 中的泛型类型。 这是我使用的代码:

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;
};

为了从每个单例中删除所有具有特定 ID 的 组件,我必须跟踪每个已创建的单例实例。 在这一点上我被卡住了。

第一个问题是泛型类型不能保存到vector。 我会用 Baseclass 绕过它并从中派生 InternalComponent。

但是我仍然无法保存对矢量的引用。

我也不确定如何检查单例是否是第一次创建,而不是在每个 getInstance 调用中使用 if 语句,以避免在我创建的单例列表中出现重复条目​​。

我的最后一个问题是:如何在单个列表中管理每个已创建的 InternalComponent 实例。

【问题讨论】:

  • 单例不是只提供一个对象实例吗?
  • 它仍然为每种类型提供了一个实例。
  • 不要纠结于指针,最好使用Scott Meyers Singleton。如果要计算实例化了多少类型,请使用带有静态计数器变量的基类。
  • 确实,指针、动态分配和静态数据很容易变得一团糟。
  • 我有点困惑。我正在使用与您建议的完全相同的模式。指针用于以后保存的对象。而且我不想数他们。

标签: c++ templates generics singleton


【解决方案1】:

我想出了如何跟踪我创建的所有基于模板的单例。

#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);
}

我使用抽象类稍后将基于模板的类存储在向量中。该类提供了以后需要的功能。构造函数只被调用一次,这允许我存储 this 指针并避免不必要的检查。

【讨论】:

    猜你喜欢
    • 2011-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-29
    • 2015-02-25
    • 2016-03-25
    相关资源
    最近更新 更多