我的主要项目类是模板类,声明为:访问成员
template<int dim, typename typ>
其中暗淡是维数(2或3),和典型是浮点数据类型(float或double)。基于这些参数,此类的实例具有其特定类型的成员和向量(数学)具有的组件数量dim。
因此,实例可以在成员类型上有所不同,并且它们的函数在参数类型上有所不同,但它们都具有相同的函数安排......可以对运行时做些什么,即一般地访问此类的实例不同的模板参数?
我的主要项目类是模板类,声明为:访问成员
template<int dim, typename typ>
其中暗淡是维数(2或3),和典型是浮点数据类型(float或double)。基于这些参数,此类的实例具有其特定类型的成员和向量(数学)具有的组件数量dim。
因此,实例可以在成员类型上有所不同,并且它们的函数在参数类型上有所不同,但它们都具有相同的函数安排......可以对运行时做些什么,即一般地访问此类的实例不同的模板参数?
这正是继承的原因。您创建一个通用的,非模板,纯虚基类,它定义了所有的模板中使用的接口,例如:
class Base {
public:
virtual ~Base() {};
virtual void foo() = 0;
virtual int bar(int param) = 0;
// Etc, for whatever other methods you want
};
然后你从中获得您的模板:
template<int dim, typename typ>
class Dervied : public Base
{
public:
virtual ~Derived();
virtual void foo();
virtual int bar(int param);
// Etc, for whatever other methods you want
private:
std::vector<typ> data;
};
而且当然要实现Derived
模板的方法。然后,您可以通过指针或Base
的引用访问Derived
的任何实例。例如:
void callFoo(const Base& b)
{
b.foo();
}
int main()
{
Derived<3,float> d_f3;
Derived<2,double> d_d2;
callFoo(d_f3);
callFoo(d_d2);
return 0;
}
它从你的描述听起来可能有一些方法,这些方法在普通的Derived
所有实例当中,但一些依赖于模板参数,例如
void addNumber(typ number);
在这种情况下,你不能拉这个功能成Base
,因为它没有意义的呼吁一Derived<n,float>
此方法。如果有一些功能依赖于类型和一些依赖于数量,那么你可以创建基类封装的想法,像这样:
class Base
{ /* All methods independent of template parameters */ };
template <int dim> DimBase : virtual public Base
{ /* All methods dependent only on the dimension parameter */ };
template <typename typ> TypBase : virtual public Base
{ /* All methods dependent only on the type parameter */ };
template<int dim, typename typ>
Derived : public DimBase<dim>, public TypBase<typ>
{ /* All methods */ };
这将允许您使用调用任何独立的方法Base
指针或引用,使用指针或引用调用任何依赖于维度的方法,以及使用指针或引用的任何类型依赖方法。
注意,在上文中,可取的做法是Base
,TypBase
和DimBase
全部是抽象类(含有至少一种未实现的虚拟方法),它从Base
TypBase
和DimBase
继承改为使用的virtual public
是必不可少只是public
,否则你会得到“dreaded diamond”
泰勒谢谢你的回答。简单继承不是一个问题,我所遇到的最大问题是依赖于维度和类型的函数参数,例如vec
我的答案的第二部分解决了如何为依赖于维或类型的方法获取多态行为。依赖* *维和类型的方法必须在叶类中定义,并且不能多态使用。想一想:如果一个方法的参数依赖于一个类的维度和类型,那么你如何期望在一个具有不同维度和类型的类的对象上调用相同的方法?这样的事情没有任何意义。 – 2010-07-30 20:31:56
这里有什么问题?你能举出你期望如何调用这些对象的例子吗?我怀疑你不需要@Tyler McHenry的方法(这是正确的,只是可能会矫枉过正)。 我建议用你需要的方法和成员来定义这个类,并且当你有一些不会编译的东西时回到我们.-) “template struct X {void f (typ t);};“ –
2010-07-30 23:47:19