设计在C ++中的容器中一起使用所有子类

时间:2010-07-29 10:08:54

标签: c++ templates

我刚读了一篇关于奇怪的重复模板模式的文章。您可以使用它模拟模板的虚拟功能。

例如:

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*>这在使用模板时是不可能的,并且你必须在虚拟函数中使用普通的多态性基类。

解决这个问题的设计建议是什么?因为我想使用模板,但也能够在容器中一起使用所有子类。

3 个答案:

答案 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);
}