在实例化派生类时指定基类模板参数?

时间:2011-01-17 02:08:21

标签: c++ templates polymorphism

我不知道标题是否有意义,但我找不到合适的词来在一行中描述我的“问题”。无论如何,这是我的问题。有一个搜索界面:

template <typename InputType, typename ResultType> class Search {
public:
    virtual void search (InputType) = 0;
    virtual void getResult(ResultType&) = 0;

};

和几个派生类如:

template <typename InputType, typename ResultType> 
    class XMLSearch : public Search<InputType, ResultType> {
public:
    void search (InputType) { ... };
    void getResult(ResultType&) { ... };

};

稍后将在源代码中使用派生类。我想在没有指定模板参数的情况下保持一个指向Search的简单指针,然后分配一个新的XMLSearch,从而定义Search和XMLSearch的模板参数

Search *s = new XMLSearch<int, int>();

我发现了一种在语法上与我正在尝试的方式一样的方法,但真正使用它似乎有点奇怪:

template <typename T> class Derived;

class Base {
public:
 template <typename T>
 bool GetValue(T &value) {
  Derived<T> *castedThis=dynamic_cast<Derived<T>* >(this);
  if(castedThis)
   return castedThis->GetValue(value);
  return false;
 }
 virtual void Dummy() {}
};

template <typename T> class Derived : public Base {
public:
 Derived<T>() {
  mValue=17;
 }

 bool GetValue(T &value) {
  value=mValue;
  return true;
 }
 T mValue;
};

int main(int argc, char* argv[])
{
 Base *v=new Derived<int>;
 int i=0;
 if(!v->GetValue(i))
  std::cout<<"Wrong type int."<<std::endl;
 float f=0.0;
 if(!v->GetValue(f))
  std::cout<<"Wrong type float."<<std::endl;
 std::cout<<i<<std::endl<<f;
 char c;
 std::cin>>c; 
 return 0;
}

有没有更好的方法来实现这一目标?

1 个答案:

答案 0 :(得分:1)

  

有没有更好的方法来实现   此?

是的,这个设计稍好一些,因为在调用GetValue()时我正在使用静态调度(我假设dynamic_cast是拼写错误,你实际上想在static_cast中输入Base::GetValue() {1}})。在该设计中,Base::GetValue()不是虚拟的,但它能够使用Derived::GetValue()类型的指针来调用Base。这使它稍快。

但即使你的方式也不是那么糟糕。所有你要实例化你的类模板:

Search<int,int> *s = new XMLSearch<int, int>();

您的Search *s = new XMLSearch<int, int>() 错误


您可以按以下方式typedef模板:

typedef Search<int,int> iisearch;
typedef XMLSearch<int,int> iixmlsearch;

然后使用它们:

iisearch *s = new iixmlsearch();

这看起来更好,对吧?


小修改

你可以让你的课程在性能方面略微提高。为此,请按如下方式编写Search类模板:

template <typename InputType, typename ResultType> class Search {
public:
    void search (InputType input) //it's not virtual anymore!
    {
        xmlsearch *_this = getXmlSearch();
        xmlsearch->search(input);
    }
    void getResult(ResultType& result) //it's not virtual anymore!
    {
        xmlsearch *_this = getXmlSearch();
        xmlsearch->getResult(result);
    }
private:
    typedef XMLSearch<InputType, ResultType> xmlsearch;
    xmlsearch* getXmlSearch()
    {
       static xmlsearch *_this= static_cast<xmlsearch* >(this);
       return _this;
    }

};

现在你的基类不是抽象的,因为它没有定义虚函数。这个设计比你的版本快一点!