在C ++ 11/14中重写派生的模板类方法

时间:2018-10-26 22:16:03

标签: c++11 templates c++14

我需要使用createT()模板类中的方法,用不同数量的输入参数来覆盖Base模板类的方法Derived。我已经开发了这个非常简单的示例:

#include <iostream>

class Helper
{
public:
  Helper(std::string s): _s(s)
  {}

  void display()
  {
     std::cout << _s << std::endl;
  }

private:
  std::string _s;
};

class Helper2
{
public:
  Helper2(std::string s, int i):
    _s(s), _i(i)
  {}

  void display()
  {
    std::cout << _s << " + " << std::to_string(_i) << std::endl;
  }

private:
  std::string _s;
  int _i;
};

template<class T> class Base
{
public:
  Base()
  {
    _pTBase = createT();
  }

  void test()
  {
    _pTBase->display();
  }

protected:
  /// Subclasses can override this method.
  virtual T* createT()
  {
    return new T("### BASE ###");
  }

private:
 T* _pTBase;

}; //template<class T> class Base


template<class T> class Derived : public Base<T>
{
public:
  Derived() : Base<T>()
  {
    _pTDerived = createT();
  }

  void test()
  {
    _pTDerived->display();
  }

protected:
  virtual T* createT()
  {
    return new T("### DERIVED ###", 5);
  }

private:

 T* _pTDerived;

}; //template<class T> class Derived : public Base<T>


int main()
{
  Derived<Helper2> a;

  a.test();

  return 0;
}

当我尝试编译时,我收到此消息:

error: no matching function for call to ‘Helper2::Helper2(const char [13])’
     return new T("### BASE ###");
                                ^

似乎编译器不能在派生类中使用createT()方法。

当然,如果我将Base类(而不是Helper)与Helper2类一起使用,则一切正常。

解决这种情况的正确方法是什么?

1 个答案:

答案 0 :(得分:2)

构造a时,首先构造Base<Helper2>基础对象。该构造函数将调用Base::createT,这要求Helper2拥有一个带有一个参数的构造函数。由于不存在该错误,因此会出现编译错误。

构造Derived<Helper>对象时,将创建两个Helper对象:一个由Base的构造函数存储在_pTBase中,另一个由{{1 }}的构造函数,存储在Derived<Helper>中。

解决此问题的一种方法是让派生类调用(non-virtual_pTDerived函数,然后将返回的指针传递给基类构造函数。