• [笔记]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()。

  • 相关阅读:
    【集合】元组元素命名
    普通数组-队列
    稀疏数组
    Java基础 07 API概述 Scanner类 Random类 ArrayList类
    Java基础 06 类与对象、封装、构造方法
    Java基础 05 数组
    Java基础 04 IDEA、方法
    Java基础 04 [附] IDEA 的安装、配置与使用
    Java基础 03 流程控制语句
    Java基础 02 数据类型转换、运算符、方法入门
  • 原文地址:https://www.cnblogs.com/journeyonmyway/p/2567215.html
Copyright © 2020-2023  润新知