我有一个带有几个纯虚方法的基类,例如
class GenericFunction
{
public:
GenericFunction() { /* Init generic function state */ };
virtual void Iterate(short *ps, unsigned cs) = 0;
virtual void Iterate(float *ps, unsigned cs) = 0;
}
然后我有一堆实现特定函数的派生类,我想在这些函数的集合上调用Iterate()
方法,为每个函数提供一个数据样本块。我只知道我正在调用Iterate()
时的数据类型。
Iterate()
方法对于许多函数几乎完全相同,所以我想使用模板。我不能在基类中使用模板,因为不允许使用虚拟模板。为了让编译器从模板生成正确的方法,我发现我必须像这样使用对模板的间接调用:
class SpecificFunction : GenericFunction
{
public:
SpecificFunction() : GenericFunction() { /* Init specific function state */ };
template<class T> void IterateT(T *ps, unsigned cs) {
// Do function operations on block of samples
};
virtual void Iterate(short *ps, unsigned cs) { IterateT(ps, cs); };
virtual void Iterate(float *ps, unsigned cs) { IterateT(ps, cs); };
}
我不想让SpecificFunction
的整个类成为模板,因为还有许多其他方法,并且所有代码都与正在操作的样本类型无关。我不希望在从模板生成代码时复制所有代码,因为它是在嵌入式处理器上运行且代码空间有限。
这看起来很复杂且效率低下。有更好的方法吗?
答案 0 :(得分:1)
这是一个可怕的钻石(虚拟继承和多重继承)可以帮助你的情况。您可以使用几乎从GenericFunction
继承的模板代理类作为常用实现。然后,对要创建SpecificFunction
。
class ProxyState;
template <typename T>
class ProxyFunction : public virtual GenericFunction
{
public:
ProxyFunction() : GenericFunction() {};
virtual ProxyState * state () { return 0; }
void Iterate (T *ps, unsigned cs) {
// Do function operations on block of samples, using state()
// if necessary
std::cout << __PRETTY_FUNCTION__ << "\n";
}
};
class SpecificFunction : public ProxyFunction<short>,
public ProxyFunction<float>
{
public:
SpecificFunction() : ProxyFunction<short>(),
ProxyFunction<float>()
{ /* Init specific function state */ };
};
//...
SpecificFunction s;
GenericFunction *g = &s;
g->Iterate((short *)0, 0);
g->Iterate((float *)0, 0);
上述程序给出了以下输出:
void ProxyFunction<T>::Iterate(T*, unsigned int) [with T = short int]
void ProxyFunction<T>::Iterate(T*, unsigned int) [with T = float]
图示,图表如下:
GenericFunction
|
/_\ (virtual)
|
ProxyFunction<T>
|
____________|____________
| |
ProxyFunction<short> ProxyFunction<float>
| |
/_\ /_\
|_______ _______|
| |
SpecificFunction
由于GenericFunction
是虚拟继承的,SpecificFunction
只有一个实例,即使它继承了多个ProxyFunction<>
。