gpt4 book ai didi

c++ - 模板重构

转载 作者:行者123 更新时间:2023-11-30 03:07:37 25 4
gpt4 key购买 nike

假设我们有几种类型的元素,我们想创建一个每种类型的“经理”。经理负责任何元素的创建、激活/停用和删除(我们假设用户不会创建/销毁这些元素的实例不使用经理。一个非常简单的代码示例如下所示:

template <class T>
class NonCachedElementMngr
{
public:
NonCachedElementMngr():
rmCounter(0)
{}

~ NonCachedElementMngr()
{
T* element = 0;
if(mElements.size() > 0)
{
typename std::set<T*>::iterator it;
for(it = mElements.begin(); it != mElements.end(); ++it)
{
element = *it;
element->deactivate();
delete element;
}
}
}

T* create()
{
T* element = new T();
element->activate();
mElements.insert(element);
return element;
}

bool release(T* element)
{
bool ret = false;
typename std::set<T*>::iterator it;
it = mElements.find(element);
if(it != mElements.end())
{
element->deactivate();
delete element;
mElements.erase(it);
ret = true;
}
return ret;
}

private:

std::set<T*> mElements;
int rmCounter;
};

现在让我们想象一下,对于对象的一个​​子组,除了基本的操作,我们还需要做一些缓存。对于那个类型子组,我们可以像这样定义另一个“经理”:

template <class T>
class CachedElementMngr
{
public:
CachedElementMngr():
rmCounter(0)
{}

~CachedElementMngr()
{
T* element = 0;
if(mElements.size() > 0)
{
typename std::set<T*>::iterator it;
for(it = mElements.begin(); it != mElements.end(); ++it)
{
element = *it;
element->removeFromCache(); // <<<<<<<<<<<<<< Different line
element->deactivate();
delete element;
}
}
}

T* create()
{
T* element = new T();
element->storeInCache(); // <<<<<<<<<<<<<< Different line
element->activate();
mElements.insert(element);
return element;
}

bool release(T* element)
{
bool ret = false;
typename std::set<T*>::iterator it;
it = mElements.find(element);
if(it != mElements.end())
{
element->removeFromCache(); // <<<<<<<<<<<<<< Different line
element->deactivate();
delete element;
mElements.erase(it);
ret = true;
}
return ret;
}

private:

std::set<T*> mElements;
int rmCounter;
};

很明显,除了三行标记为如此。我该如何重构这两个模板?我们在编译时知道特定类型是否可缓存。请注意,析构函数中也有不同的行。任何可行的建议(虚拟继承、模板特化、SFINAE...)都将受到欢迎。

最佳答案

将特定行为分解为策略:

#include <set>

struct cached_tag;
struct noncached_tag;

template<typename Tag>
struct ElementMngrCachePolicy;

template<>
struct ElementMngrCachePolicy<cached_tag>
{
template<typename T>
static void removeFromCache(T* const element) { /*impl...*/ }

template<typename T>
static void storeInCache(T* const element) { /*impl...*/ }
};

template<>
struct ElementMngrCachePolicy<noncached_tag>
{
template<typename T>
static void removeFromCache(T* const) { /*do nothing*/ }

template<typename T>
static void storeInCache(T* const) { /*do nothing*/ }
};

template<typename T, typename CachePolicy>
class ElementMngr
{
typedef std::set<T*> elements_t;

public:
ElementMngr() :
rmCounter()
{ }

~ElementMngr()
{
for (typename elements_t::iterator it = mElements.begin(); it != mElements.end(); ++it)
{
T* const element = *it;
CachePolicy::removeFromCache(element);
element->deactivate();
delete element;
}
}

T* create()
{
T* const element = new T();
CachePolicy::storeInCache(element);
element->activate();
mElements.insert(element);
return element;
}

bool release(T* const element)
{
typename elements_t::iterator it = mElements.find(element);
if (it == mElements.end())
return false;

CachePolicy::removeFromCache(element);
element->deactivate();
delete element;
mElements.erase(it);
return true;
}

private:
elements_t mElements;
int rmCounter;
};

template<typename T>
class CachedElementMngr : public ElementMngr<T, ElementMngrCachePolicy<cached_tag> >
{ };

template<typename T>
class NonCachedElementMngr : public ElementMngr<T, ElementMngrCachePolicy<noncached_tag> >
{ };

关于c++ - 模板重构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5741146/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com