问题描述
我有一个基类,我做了一个模板,因为我想改变它需要的几个函数的类型,但我想从这些模板化的基类派生。我想存储这些类的向量。我的想法是在层次结构中的所有事物上创建一个非模板化的基类,并使用双调度来确定类型。
I have a base class that I made a template because I want to vary the type it takes for several functions, but I want to derive from these templated base classes. I want to store a vector of these classes. My idea was to create a non-templated base class above everything in the hierarchy, and use double dispatching to figure out the type. Am I doing this the "right way"?
这是一个场景的代码片段:
Here's a code snippet of the scenario:
class FooBase
{
public:
virtual void Accept( Visitor &v );
};
template<class T>
class Foo : public FooBase
{
public:
virtual void DoThing( const T & );
virtual void Accept( Visitor &v) = 0;
};
template<>
class Foo<Bar> : public FooBase
{
public:
virtual void Accept( Visitor &v )
{
v.HandleBar( *this );
}
};
template<>
class Foo<Baz> : public FooBase
{
public:
virtual void Accept( Visitor &v )
{
v.HandleBaz( *this );
}
};
//和许多Foo,Foo派生类
// and many derived classes from Foo, Foo
然后在另一个类
class Visitor
{
public:
virtual void HandleBar( Foo<Bar> &f ) = 0;
virtual void HandleBaz( Foo<Baz> &f ) = 0;
};
class Manager : public Visitor
{
public:
void AddFoo( FooBase& f )
{
a.push_back( f );
}
void RunAll()
{
for ( std::vector<std::shared_ptr<FooBase> >::iterator it = a.begin(); it != a.end(); ++it )
{
(*it)->Accept( *this );
// do common action that doesn't depend on types
}
}
virtual void HandleBar( Foo<Bar> &f )
{
Bar item = GetBarItemFunction(); // not shown
f.DoThing( item );
}
virtual void HandleBaz( Foo<Baz> &f )
{
Baz item = GetBazItemFunction(); // not shown
f.DoThing( item );
}
private:
std::vector<std::shared_ptr<FooBase> > a;
};
我只是不知道这是否是最好的方式。我可以使用dynamic_casting,但是感觉脏。那么这是一个坚实的解决方案吗?请指示(我希望我没有在示例中留下任何明显的语法错误)
I just don't know if this is the "best" way to do it. I could use dynamic_casting, but that feels dirty. So is this a solid solution to the situation? Please advise (I hope I didn't leave any glaring syntax errors in the example)
(编辑删除,我的部分是愚蠢的错误)
(EDIT removed, was stupid error on my part)
推荐答案
我想你差不多了。我写的访问者类如下:
I think you've almost got it. I would write the visitor class like:
class Visitor
{
public:
virtual void HandleFoo( Foo<Bar> &f ) = 0;
virtual void HandleFoo( Foo<Baz> &f ) = 0;
//default implementation for unknown Foo types:
virtual void HandleFoo( FooBase &f ) = 0;
};
现在你不需要专门化你模板化的Foo类,你可以写下面的工作与您的应用程序可能需要的所有类T。将根据Foo中使用的模板类型选择正确的重载HandleFoo函数。您仍然必须向访问者类中添加方法,以避免调用默认行为。
Now you don't need to specialize your templated Foo class and you can just write the following to work with all class T's your application may need. The correct overloaded HandleFoo function will be chosen based on the template type used in Foo. You will still have to add methods to your visitor class to avoid the default behavior being invoked.
template<class T>
class Foo : public FooBase
{
public:
virtual void DoThing( const T & );
virtual void Accept( Visitor &v) {
v.HandleFoo( *this );
};
};
这篇关于存储std :: shared_ptr< Foo>的向量其中Foo是一个模板类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!