C++;multiton模式的模板化类实现 我使用C++中的模板类实现了多模式, #ifndef MULTITON_H #define MULTITON_H #include <map> template <typename Key, typename T> class Multiton { public: static void destroy() { for (typename std::map<Key, T*>::iterator it = instances.begin(); it != instances.end(); ++it) { delete (*it).second; } } static T& getRef(const Key& key) { typename std::map<Key, T*>::iterator it = instances.find(key); if (it != instances.end()) { return *(T*)(it->second); } T* instance = new T; instances[key] = instance; return *instance; } static T* getPtr(const Key& key) { typename std::map<Key, T*>::iterator it = instances.find(key); if (it != instances.end()) { return (T*)(it->second); } T* instance = new T; instances[key] = instance; return instance; } protected: Multiton() {} virtual ~Multiton() {} private: Multiton(const Multiton&) {} Multiton& operator= (const Multiton&) { return *this; } static std::map<Key, T*> instances; }; template <typename Key, typename T> std::map<Key, T*> Multiton<Key, T>::instances; #endif \ifndef MULTITON\u H #定义MULTITON_H #包括 模板类Multiton { 公众: 静态空洞破坏() { 对于(typename std::map::iterator it=instances.begin();it!=instances.end();++it){ 删除(*it); } } 静态T&getRef(常数键和键) { typename std::map::iterator it=instances.find(key); if(it!=instances.end()){ 返回*(T*)(它->秒); } T*实例=新的T; 实例[键]=实例; 返回*实例; } 静态T*getPtr(常数键和键) { typename std::map::iterator it=instances.find(key); if(it!=instances.end()){ 返回(T*)(它->秒); } T*实例=新的T; 实例[键]=实例; 返回实例; } 受保护的: Multiton(){} 虚拟~Multiton(){} 私人: 多声子(常数多声子&){} Multiton&运算符=(常量Multiton&){return*this;} 静态std::map实例; }; 模板std::map Multiton::instances; #恩迪夫

C++;multiton模式的模板化类实现 我使用C++中的模板类实现了多模式, #ifndef MULTITON_H #define MULTITON_H #include <map> template <typename Key, typename T> class Multiton { public: static void destroy() { for (typename std::map<Key, T*>::iterator it = instances.begin(); it != instances.end(); ++it) { delete (*it).second; } } static T& getRef(const Key& key) { typename std::map<Key, T*>::iterator it = instances.find(key); if (it != instances.end()) { return *(T*)(it->second); } T* instance = new T; instances[key] = instance; return *instance; } static T* getPtr(const Key& key) { typename std::map<Key, T*>::iterator it = instances.find(key); if (it != instances.end()) { return (T*)(it->second); } T* instance = new T; instances[key] = instance; return instance; } protected: Multiton() {} virtual ~Multiton() {} private: Multiton(const Multiton&) {} Multiton& operator= (const Multiton&) { return *this; } static std::map<Key, T*> instances; }; template <typename Key, typename T> std::map<Key, T*> Multiton<Key, T>::instances; #endif \ifndef MULTITON\u H #定义MULTITON_H #包括 模板类Multiton { 公众: 静态空洞破坏() { 对于(typename std::map::iterator it=instances.begin();it!=instances.end();++it){ 删除(*it); } } 静态T&getRef(常数键和键) { typename std::map::iterator it=instances.find(key); if(it!=instances.end()){ 返回*(T*)(它->秒); } T*实例=新的T; 实例[键]=实例; 返回*实例; } 静态T*getPtr(常数键和键) { typename std::map::iterator it=instances.find(key); if(it!=instances.end()){ 返回(T*)(它->秒); } T*实例=新的T; 实例[键]=实例; 返回实例; } 受保护的: Multiton(){} 虚拟~Multiton(){} 私人: 多声子(常数多声子&){} Multiton&运算符=(常量Multiton&){return*this;} 静态std::map实例; }; 模板std::map Multiton::instances; #恩迪夫,c++,singleton,design-patterns,multiton,C++,Singleton,Design Patterns,Multiton,用法: class Foo : public Multiton<std::string, Foo> {}; Foo& foo1 = Foo::getRef("foobar"); Foo* foo2 = Foo::getPtr("foobar"); Foo::destroy(); class Foo:public Multiton{}; Foo&foo1=Foo::getRef(“foobar”); Foo*foo2=Foo::getPtr(“foobar”); Foo::d

用法:

class Foo : public Multiton<std::string, Foo> {};
Foo& foo1 = Foo::getRef("foobar");
Foo* foo2 = Foo::getPtr("foobar");
Foo::destroy();
class Foo:public Multiton{};
Foo&foo1=Foo::getRef(“foobar”);
Foo*foo2=Foo::getPtr(“foobar”);
Foo::destroy();

有任何改进建议吗?

一个改进是重写
getRef
以使用
getPtr
(反之亦然,方向并不重要):

1) 个人偏好,但我会颠倒模板参数的顺序,并将键默认为std::string(如果这是您最常用的)

6) 如果您没有使用多态T,那么您可以使用std::map,您的代码如下所示

template <typename Key, typename T> class Multiton
{
public:
    //Can probably get rid of this guy as maps destructor will do the right thing 
    static void destroy()
    {
        instances.clear();
    }

    static T& getRef(const Key& key)
    {
        return instances[key];
    }

    static T* getPtr(const Key& key)
    {
        return &instances[key];
    }

protected:
    Multiton() {}
    virtual ~Multiton() {}

private:
    Multiton(const Multiton&) {}
    Multiton& operator= (const Multiton&) { return *this; }

    static std::map<Key, T> instances;
};
模板类Multiton
{
公众:
//也许可以干掉这个家伙,因为地图析构函数会做正确的事情
静态空洞破坏()
{
实例。清除();
}
静态T&getRef(常数键和键)
{
返回实例[key];
}
静态T*getPtr(常数键和键)
{
返回&实例[key];
}
受保护的:
Multiton(){}
虚拟~Multiton(){}
私人:
多声子(常数多声子&){}
Multiton&运算符=(常量Multiton&){return*this;}
静态std::map实例;
};

这就是我目前所能想到的一切。

看来你做得非常出色

顺便说一句,我可以问你为什么在这里铸造实例(c风格)

我想如果你写下来会更干净

return it->second;
此外,由于该职位已有10年历史, 我用现代的C++方式对一个版本进行了一点修改,使用了智能指针。 请看一看

multiton.h

#ifndef MULTITON_H
#define MULTITON_H

#include <map>
#include <string>

template <typename T, typename Key = int> class Multiton {
  public:
    static void DestroyAll();
    static void Destroy(const Key &key);
    static std::shared_ptr<T> GetPtr(const Key &key);
    static T &GetRef(const Key &key) { return *GetPtr(key); }

  protected:
    Multiton();
    ~Multiton();

  private:
    Multiton(const Multiton &) = default;
    Multiton &operator=(const Multiton &) = default;
    static std::map<Key, std::shared_ptr<T>> instances_;
};

#endif // MULTITON_H
\ifndef MULTITON\u H
#定义MULTITON_H
#包括
#包括
模板类Multiton{
公众:
静态void DestroyAll();
静态空洞破坏(常数键和键);
静态std::共享\u ptr GetPtr(const Key和Key);
静态T&GetRef(const Key&Key){return*GetPtr(Key);}
受保护的:
Multiton();
~Multiton();
私人:
Multiton(常数Multiton&)=默认值;
Multiton&运算符=(常量Multiton&)=默认值;
静态std::映射实例;
};
#endif//MULTITON\u H
multiton.cpp

#include "multiton.h"
template <typename T, typename Key> void Multiton<T, Key>::DestroyAll() {
    for (auto it = instances_.begin(); it != instances_.end(); ++it)
        delete (*it).second;
    instances_.clear();
}

template <typename T, typename Key> void Multiton<T, Key>::Destroy(const Key &key) {
    auto it = instances_.find(key);

    if (it != instances_.end()) {
        delete (*it).second;
        instances_.erase(it);
    }
}

template <typename T, typename Key> std::shared_ptr<T> Multiton<T, Key>::GetPtr(const Key &key) {
    const auto it = instances_.find(key);

    if (it != instances_.end())
        return (it->second);

    std::shared_ptr<T> instance = std::make_shared<T>();
    instances_[key] = instance;
    return instance;
}

template <typename T, typename Key> Multiton<T, Key>::Multiton() {}

template <typename T, typename Key> Multiton<T, Key>::~Multiton() {}

template <typename T, typename Key> std::map<Key, std::shared_ptr<T>> Multiton<T, Key>::instances_;
#包括“multiton.h”
模板void Multiton::DestroyAll(){
for(auto it=instances_u.begin();it!=instances_u.end();++it)
删除(*it);
实例清除();
}
模板无效Multiton::销毁(常量键和键){
自动it=实例查找(键);
if(it!=instances\uu.end()){
删除(*it);
实例:删除(它);
}
}
模板std::shared_ptr Multiton::GetPtr(常量键和键){
const auto it=实例查找(键);
if(it!=instances\uu.end())
返回(它->秒);
std::shared_ptr instance=std::make_shared();
实例u[key]=实例;
返回实例;
}
模板Multiton::Multiton(){}
模板Multiton::~Multiton(){}
模板std::map Multiton::实例;

很有趣。当我写下这个答案时,我不知道有一个“多音”模式:。我使用这个术语的意思完全不同:)关于你的第6点-你能详细说明使用这个简化代码的确切条件吗?T的非多态性在哪里发挥作用?如果你把一个从
T
派生的
D
类型的对象放到映射中,它会被切回它的基类T-类似于调用
T temp=D
所做的-编译器甚至可能不会告诉你。事实上,如果T是一个抽象类,你甚至无法创建映射,所以整个过程都无法编译。
template <typename Key, typename T> class Multiton
{
public:
    //Can probably get rid of this guy as maps destructor will do the right thing 
    static void destroy()
    {
        instances.clear();
    }

    static T& getRef(const Key& key)
    {
        return instances[key];
    }

    static T* getPtr(const Key& key)
    {
        return &instances[key];
    }

protected:
    Multiton() {}
    virtual ~Multiton() {}

private:
    Multiton(const Multiton&) {}
    Multiton& operator= (const Multiton&) { return *this; }

    static std::map<Key, T> instances;
};
return (T*)(it->second);
return it->second;
#ifndef MULTITON_H
#define MULTITON_H

#include <map>
#include <string>

template <typename T, typename Key = int> class Multiton {
  public:
    static void DestroyAll();
    static void Destroy(const Key &key);
    static std::shared_ptr<T> GetPtr(const Key &key);
    static T &GetRef(const Key &key) { return *GetPtr(key); }

  protected:
    Multiton();
    ~Multiton();

  private:
    Multiton(const Multiton &) = default;
    Multiton &operator=(const Multiton &) = default;
    static std::map<Key, std::shared_ptr<T>> instances_;
};

#endif // MULTITON_H
#include "multiton.h"
template <typename T, typename Key> void Multiton<T, Key>::DestroyAll() {
    for (auto it = instances_.begin(); it != instances_.end(); ++it)
        delete (*it).second;
    instances_.clear();
}

template <typename T, typename Key> void Multiton<T, Key>::Destroy(const Key &key) {
    auto it = instances_.find(key);

    if (it != instances_.end()) {
        delete (*it).second;
        instances_.erase(it);
    }
}

template <typename T, typename Key> std::shared_ptr<T> Multiton<T, Key>::GetPtr(const Key &key) {
    const auto it = instances_.find(key);

    if (it != instances_.end())
        return (it->second);

    std::shared_ptr<T> instance = std::make_shared<T>();
    instances_[key] = instance;
    return instance;
}

template <typename T, typename Key> Multiton<T, Key>::Multiton() {}

template <typename T, typename Key> Multiton<T, Key>::~Multiton() {}

template <typename T, typename Key> std::map<Key, std::shared_ptr<T>> Multiton<T, Key>::instances_;