[笔记]C++代码演示SingletonMap 单类Map实例

与上一篇《[笔记]C++代码演示Singleton单类实例》不同,本篇演示的是利用 STL 里的 map 和 list 容器,根据索引 key 的不同,返回不同的单实例类,调用举例如下:

MySingletonMap* MySM1 = SingletonMap<MySingletonMap>::GetInstance(1);

UML类图如下:

由上图易知,SingletonMap 是模板类,MySingletonMap 继承自 SingletonMap,具体代码如下:

#include <iostream>
#include <map>
#include <list>

using namespace std;

// 使用 map 存放单类实例的基类
template <class T, typename K = int>
class SingletonMap{
public:
    // 先从 map 中根据 key 查找实例,如果没有就创建实例
    static T* GetInstance(K key){
        // 根据 key 查找实例
        typename map<K, T*>::iterator iter = GetMap().find(key);

        // 如果找到,就返回
        if (iter != GetMap().end()){
            return iter->second;
        }

        // 否则创建新的实例
        // 此处会进到构造函数 SingletonMap(K key) 里面,将实例插入 map 和 list 中
        return new T(key);
    }

    // 返回实例列表
    static list<T*>& GetAllInstances(){
        static list<T*> List;
        return List;
    }

    // 删除全部实例
    static void DeleteAllInstances() {
        list<T*>& List = GetAllInstances();
        list<T*>::iterator v;

        // 遍历 list 内的实例
        for(v = List.begin(); v != List.end();){
            cout << "Delete Instance " << ((T*)(*v))->getKey() << endl;
            delete *v;          // 删除该项对应的实例
            v = List.erase(v);  // 从 list 中删除该项
        }
    }

    // 获得 key
    K getKey() const {
        return m_Key;
    }

protected:
    SingletonMap(K key): m_Key(key){
        pair<const K, T*> Elem(key, (T*)this);  // 创建 pair
        GetMap().insert(Elem);                  // 将 pair 插入 map
        GetAllInstances().push_back((T*)this);  // 将自身插入 list
    }

private:
    static map<K, T*>& GetMap(){
        static map<K, T*> Map;                  // 此处生成静态 map
        return Map;
    }

    K m_Key;                                    // key
};

// 继承自 SingletonMap 的子类
class MySingletonMap: public SingletonMap<MySingletonMap>{
private:
    friend class SingletonMap<MySingletonMap>;  // 将 SingletonMap 设为 friend class

    MySingletonMap(int key): SingletonMap<MySingletonMap>(key){}

    virtual ~MySingletonMap(){}
};

int main(int argc, char* argv[])
{
    MySingletonMap* MySM1 = SingletonMap<MySingletonMap>::GetInstance(1); // 创建新实例
    cout << "Number of instances = " << MySingletonMap::GetAllInstances().size() << endl; // 返回1

    MySingletonMap* MySM2 = SingletonMap<MySingletonMap>::GetInstance(2); // 创建新实例
    cout << "Number of instances = " << MySingletonMap::GetAllInstances().size() << endl; // 返回2

    MySingletonMap* MySM3 = SingletonMap<MySingletonMap>::GetInstance(2); // 得到实例 MySM2
    cout << "Number of instances = " << MySingletonMap::GetAllInstances().size() << endl; // 返回2

    if (MySM2 == MySM3) {
        cout << "MySM2 == MySM3" << endl;   // 因为二者相等,所以打印 MySM2 == MySM3
    } else {
        cout << "MySM2 != MySM3" << endl;
    }

    MySingletonMap::DeleteAllInstances();   // 删除全部实例

    getchar();
    return 0;
}

VC2010编译运行,结果为:

Number of instances = 1
Number of instances = 2
Number of instances = 2
MySM2 == MySM3
Delete Instance 1
Delete Instance 2

可见无需显式实例化,即可通过不同的索引得到不同的类单实例,这是用到了内含的 map。

如果需要遍历全部的实例,也可以利用内含的 list 进行迭代。

需要注意的是,上面代码并没有对由此获得的每个单实例的析构做处理,这一步就留给有兴趣者吧。

好吧,代码已经更新,提供了对全部实例的析构函数 DeleteAllInstances()。

原文地址:https://www.cnblogs.com/journeyonmyway/p/2567215.html