我刚读了一篇关于奇怪的重复模板模式的文章。您可以使用它模拟模板的虚拟功能。
例如:
template<class T>
struct A
{
void func() { static_cast<T*>(this)->func(); }
};
struct B : public A<B>
{
void func() { cout << "B" << endl; }
};`
但是,如果我们有很多来自A的子类并希望将它们全部放在向量中,例如,vector<A*>
这在使用模板时是不可能的,并且你必须在虚拟函数中使用普通的多态性基类。
解决这个问题的设计建议是什么?因为我想使用模板,但也能够在容器中一起使用所有子类。
答案 0 :(得分:5)
你可以这样做:
class NonTemplateBase
{
};
template<class T>
struct A : public NonTemplateBase
{
void func() { static_cast<T*>(this)->func(); }
};
然后创建一个指向NonTemplateBase
的指针向量(即std::vector<NonTemplateBase *>
)。
但是,我猜你希望能够在向量中的对象上调用func()
或其他成员函数 - 并且您希望这些调用以多态方式调用派生类中的正确成员函数。
这不会起作用,因为奇怪的重复模板模式只允许您执行静态(即编译时)多态。如果您想要运行时多态性,则必须使用虚函数。
答案 1 :(得分:1)
为模板类定义非模板抽象基类。使用基类来处理容器。
答案 2 :(得分:0)
让所有模板实现一个通用接口,并创建一个指针向量或对该接口的引用。
class Icommon //interface
{
public:
virtual void print() = 0;
};
template <class T>
class MyCommon : public Icommon
{
T obj;
public:
MyCommon(T o):obj(o) {}
void print() {cout << obj;}
};
main()
{
MyCommon<int> i(1);
MyCommon<char> c('t');
vector<Icommon *> commonVec;
commonVec.push_back(&i);
commonVec.push_back(&c);
}