抽象类的模板类

时间:2015-11-08 12:45:13

标签: c++ templates abstract-class

所以我有一个班级模板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抽象类......

忘记使用模板类?

2 个答案:

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