所以我有一个班级模板Foo
:
template <typename T>
class Foo
{
public:
Foo();
~Foo();
//...
};
我有两个来自Foo类的派生类:
class FooDerived1 : public Foo<int>
{
public:
FooDerived1 ();
~FooDerived1 ();
};
class FooDerived2 : public Foo<double>
{
public:
FooDerived2 ();
~FooDerived2 ();
};
但现在我看到类模板正在这样的抽象类IBar
上使用:
class Foo;
class IBar
{
public:
virtual void placeFoo(Foo& foo) = 0; //error
virtual void removeFoo(Foo& foo) = 0;
};
我知道我不能在抽象虚拟类中使用模板类。
但是..在这样的情况下,我该怎么办?
我真的需要像这样的IBar抽象类......
忘记使用模板类?
答案 0 :(得分:1)
选项1:使IBar
本身成为模板类。
template <class T>
class Foo;
template <class T>
class IBar
{
public:
virtual void placeFoo(Foo<T>& foo) = 0;
virtual void removeFoo(Foo<T>& foo) = 0;
};
选项2:让所有Foo<T>
派生于一个共同的非通用FooBase
。
class FooBase
{
// ...
};
template <typename T>
class Foo : public FooBase
{
public:
Foo();
~Foo();
//...
};
// ...
class FooBase;
class IBar
{
public:
virtual void placeFoo(FooBase& foo) = 0;
virtual void removeFoo(FooBase& foo) = 0;
};
两种解决方案的可行性取决于您实际依赖T
类型的程度。但是,当您将虚拟功能与模板混合时,您应该期待什么。使用选项1,您不再具有通用接口类型;对于选项2,FooBase
不能提供任何具有T
依赖参数的成员函数。
顺便说一下,不要忘记真实代码中的虚拟析构函数。
答案 1 :(得分:1)
如果您需要常见行为,请为Foo<>
的所有实例创建基类:
class FooBase
{
//common interface and data
};
template <class T>
class Foo : public FooBase
{
};
然后:
class FooBase;
class IBar
{
public:
virtual void placeFoo(FooBase& foo) = 0; //ok
virtual void removeFoo(FooBase& foo) = 0;
};
问题是,你试图混合模板(编译时)和动态多态(运行时),这可能是有问题的(它是你的意思“我知道我不能在抽象虚拟类中使用模板类“?)。
为什么不坚持使用模板?
class IBar
{
public:
template <class T>
void placeFoo(Foo<T>& foo);
template <class T>
void removeFoo(Foo<T>& foo);
};
或:
template <class T>
class IBar
{
public:
void placeFoo(Foo<T>& foo);
void removeFoo(Foo<T>& foo);
};