policy
2024-08-20 15:08:18
template <class Apolicy>
class Host
{
Apolicy direct_policy_use;
Apolicy <SomeInternalType> InternalClone; // Problem 1: Can't do this
};
template <class T, template <class T> class Apolicy>
class Host2
{
Apolicy <T> common_use;
Apolicy <SomeInternalType> InternalClone;
// Can do this now but
// Problem 2: policies that require more than one type parameter can't participate.
};
Solution and Sample Code[edit]
A member template struct (called rebind) is used to pass a different type parameter to the policy class template. For example,
template <typename T>
class NiftyAlloc
{
public:
template <typename Other>
struct rebind // The Policy Clone idiom
{
typedef NiftyAlloc <Other> other;
};
//...
};
template <typename T, class Alloc = NiftyAlloc <T> >
class Vector
{
public:
typedef typename Alloc::template rebind<long>::other ClonePolicy;
// Here, Alloc may not be a template class or a parametrized instantiation of
// a class that takes unknown number of type parameters.
};
#include <iostream>
#include <vector>
#include <list>
using namespace std;
class SliderWidget
{
public:
SliderWidget()
{
std::cout<<"Slider Widget created"<<std::endl;
}
};
class BoxWidget
{
public:
BoxWidget()
{
std::cout<<"Box Widget created"<<std::endl;
}
};
template <class T>
class OpNewCreateor
{
public:
static T* create()
{
return new T;
}
protected:
~OpNewCreateor(){}
};
template <class T>
class MallocCreator
{
public:
static T* create()
{
void * buf = std::malloc(sizeof(T));
if(!buf) return 0;
return new(buf) T;
}
protected:
~MallocCreator(){}
};
template <class T>
class PrototypeCreator
{
public:
PrototypeCreator(T* pObj = 0)
:pPrototype(pObj)
{
}
T* create()
{
return pPrototype ? pPrototype->clone() : 0;
}
T* getPrototype(){return pPrototype;}
void setPrototype(T*pObj){pPrototype = pObj;}
protected:
~PrototypeCreator(){}
private:
T* pPrototype;
};
template<class T>
class ContainerVec
{
public:
void push(T* widget)
{
mVecContainer.push_back(widget);
}
~ContainerVec(){}
private:
std::vector<T*> mVecContainer;
};
template <class T>
class ContainerList
{
public:
void push(T* widget)
{
mListContainer.insert(widget);
}
~ContainerList(){}
private:
std::list<T*> mListContainer;
};
template <
class T,
template<class > class CreationPolicy = MallocCreator,
template<class > class Container = ContainerVec
>
class WidgetManager :public CreationPolicy<T>
{
public:
typedef CreationPolicy<T> BaseClass;
T* create()
{
T* tmp = BaseClass::create();
mContainer.push(tmp);
return tmp;
}
private:
Container<T> mContainer;
};
typedef WidgetManager<BoxWidget,OpNewCreateor,ContainerVec> BoxWidgetManager;
typedef WidgetManager<SliderWidget,OpNewCreateor,ContainerList> SliderWidgetManager;
int main()
{
BoxWidgetManager boxWidgetManager;
BoxWidget * boxWidget = boxWidgetManager.create();
cout << typeid(BoxWidgetManager).name() << endl;
system( "pause");
}
最新文章
- Android 6.0 使用HttpURLConnection 使用Get提交遇到405等问题。
- 『TCP/IP详解——卷一:协议』读书笔记——12
- Spark入门实战系列--9.Spark图计算GraphX介绍及实例
- HtmlHelper使用大全
- sublime Text及package control的安装
- Android 自定义RadioButton的样式
- Lucene的Query类介绍
- 机务UI设计小节
- Ueditor之SAE移植
- 苹果4S
- 关于Oracle开启自动收集统计信息的SPA测试
- 深度学习最全优化方法总结比较(SGD,Adagrad,Adadelta,Adam,Adamax,Nadam)(转)
- WCF之endpoint的binding属性
- 【框架】selenium网页端的基本自动化框架(四)
- UE常用快捷键使用
- 使用libvirt管理KVM(一)
- 解决 dotNetZip 解压乱码的问题,支持ZIP分卷解压缩
- linux和windows时间同步问题(UTC&;localtime)
- activiti设置流程变量
- Xcode 快捷键及代码格式化