【问题标题】:How to call a templated method in a derived class that implements a pure virtual method in the base class?如何在基类中实现纯虚方法的派生类中调用模板化方法?
【发布时间】:2013-07-24 16:26:41
【问题描述】:

我有一个带有几个纯虚方法的基类,例如

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 的整个类成为模板,因为还有许多其他方法,并且所有这些代码都与正在操作的样本类型无关。我不希望所有从模板生成的代码都被复制,因为它在嵌入式处理器上运行并且代码空间有限。

这似乎令人费解且效率低下。有没有更好的方法来做到这一点?

【问题讨论】:

  • 作为旁注:不要忘记制作基本析构函数virtual
  • 您可以仅使用模板化代码模板化 SpecificFunction 的子类。
  • all 子迭代函数是否调用IterateT?还是有些有自己不同的实现方式?
  • @John:但是我不是必须将 GenericFunction 也设为模板,以便实现一个 Iterate() 方法吗?这听起来很有希望,但它究竟是如何工作的呢?
  • @MarkB:有些孩子有不同的实现,使用内联汇编来加速他们。这些派生类不使用模板,只有short *float * 的两个Iterate() 方法。

标签: c++ templates inheritance


【解决方案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&lt;&gt;s。

【讨论】:

    猜你喜欢
    • 2019-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-22
    • 2015-07-12
    • 2016-08-17
    • 1970-01-01
    相关资源
    最近更新 更多