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

发布于 2024-10-12 22:45:46 字数 1649 浏览 1 评论 0 原文

我不知道标题是否有意义,但我找不到合适的词语来形容我的“问题”。无论如何,这是我的问题。有一个用于搜索的接口:

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;
}

有更好的方法来实现这一点吗?

I have no idea if the title makes any sense but I can't find the right words to descibe my "problem" in one line. Anyway, here is my problem. There is an interface for a search:

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

};

and several derived classes like:

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

};

The derived classes shall be used in the source code later on. I would like to hold a simple pointer to a Search without specifying the template parameters, then assign a new XMLSearch and thereby define the template parameters of Search and XMLSearch

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

I found a way that works syntactically like what I'm trying to do, but it seems a bit odd to really use it:

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;
}

Is there a better way to accomplish this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

九局 2024-10-19 22:45:46

有没有更好的方法来实现
这个?

是的,这个设计稍微好一点,因为在调用 GetValue() 时使用静态调度(我假设 dynamic_cast 是拼写错误,你实际上想要输入 Base::GetValue() 中的 >static_cast)。在该设计中,Base::GetValue() 不是虚拟的,但它可以使用以下指针调用 Derived::GetValue()输入基础。这使得它稍微快一些。

但即使是你的方式也没有那么糟糕。您只需像这样实例化您的类模板:

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

您的 Search *s = new XMLSearch()错误


您可以按如下方式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;
    }
    
};

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

Is there a better way to accomplish
this?

Yes, that design is slightly better, since that's using static-dispatching while calling GetValue() (I'm assuming that dynamic_cast is typo, you actually wanted to type static_cast in Base::GetValue()). In that design, Base::GetValue() is not virtual, yet it is able to call Derived::GetValue() using pointer of type Base. This makes it slightly fast.

But even your way is not that bad. All you've to instantiate your class templates like this:

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

Your Search *s = new XMLSearch<int, int>() is wrong!


You can typedef your templates as follows:

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

Then use them:

iisearch *s = new iixmlsearch();

This looks better, right?


Small Modification

You can make your class slightly better performance-wise. For that, write your Search class template as follows:

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;
    }
    
};

Now your base class is not abstract, as it doesn't define virtual functions. This design is slightly faster than your version!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文