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