摘要 class 上的模板 class
Template class on a abstract class
所以我有一个 class 模板 Foo
:
template <typename T>
class Foo
{
public:
Foo();
~Foo();
//...
};
我有两个来自 Foo class 的派生 classes class:
class FooDerived1 : public Foo<int>
{
public:
FooDerived1 ();
~FooDerived1 ();
};
class FooDerived2 : public Foo<double>
{
public:
FooDerived2 ();
~FooDerived2 ();
};
但现在我看到 class 模板被用在抽象 class IBar
上,如下所示:
class Foo;
class IBar
{
public:
virtual void placeFoo(Foo& foo) = 0; //error
virtual void removeFoo(Foo& foo) = 0;
};
我知道我不能在抽象虚拟 classes 中使用模板 classes。
但是..遇到这种情况,我该怎么办?
我真的需要这样的 IBar 摘要 class...
忘记使用模板 classes?
选项 1:使 IBar
本身成为模板 class。
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
的参数。
顺便说一下,不要忘记你的真实代码中的虚拟析构函数。
如果您需要通用行为,请为 Foo<>
:
的所有实例创建基础 class
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;
};
问题是,您尝试混合使用模板(编译时)和动态多态性(运行时),这可能会有问题(这就是您所说的 "I know I cannot use templates classes in abstract virtual classes"?).
为什么不坚持使用模板?
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);
};
所以我有一个 class 模板 Foo
:
template <typename T>
class Foo
{
public:
Foo();
~Foo();
//...
};
我有两个来自 Foo class 的派生 classes class:
class FooDerived1 : public Foo<int>
{
public:
FooDerived1 ();
~FooDerived1 ();
};
class FooDerived2 : public Foo<double>
{
public:
FooDerived2 ();
~FooDerived2 ();
};
但现在我看到 class 模板被用在抽象 class IBar
上,如下所示:
class Foo;
class IBar
{
public:
virtual void placeFoo(Foo& foo) = 0; //error
virtual void removeFoo(Foo& foo) = 0;
};
我知道我不能在抽象虚拟 classes 中使用模板 classes。
但是..遇到这种情况,我该怎么办?
我真的需要这样的 IBar 摘要 class...
忘记使用模板 classes?
选项 1:使 IBar
本身成为模板 class。
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
的参数。
顺便说一下,不要忘记你的真实代码中的虚拟析构函数。
如果您需要通用行为,请为 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;
};
问题是,您尝试混合使用模板(编译时)和动态多态性(运行时),这可能会有问题(这就是您所说的 "I know I cannot use templates classes in abstract virtual classes"?).
为什么不坚持使用模板?
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);
};