模板类中是否允许使用纯虚方法?

时间:2012-01-19 00:33:30

标签: c++ templates virtual

有一次,我确信你不能这样做,但前几天我正在玩一些代码,它似乎编译和工作。我只是想证实我不仅仅是幸运。模板类可以有一个纯虚函数 - 我想这也意味着普通的虚方法对于析构函数也是有效的吗?

template <typename WordType> class DataSource
{
public:
    DataSource();
    DataSource(DataSource const& other);
    virtual ~DataSource();

    virtual void Put(
        WordType const* const data,
        unsigned int const wordCount) = 0;
}

我已经尝试在网上查找了,而且我能找到的就是你不能在正常的课程中使用虚拟方法(纯粹或其他方式),例如:

class DataSource
{
public:
    DataSource();
    DataSource(DataSource const& other);
    virtual ~DataSource();

    template <typename WordType>
    virtual void Put(
        WordType const* const data,
        unsigned int const wordCount) = 0;
}

这是由于管理虚拟表以引用此方法将会实现的所有不同类型的可能类型的不可能性。

然而,当涉及模板类的虚拟成员函数时,它似乎是不同的,因为当模板类变量被实例化时,整个类本身通过模板参数“创建”。此时,由于模板的“查找和替换”性质,虚拟方法就像任何其他类的方法一样。

无论如何,再次陈述问题,以防它丢失在那里: 在tempate类中是否允许虚拟(纯和/或普通)虚函数?

4 个答案:

答案 0 :(得分:51)

类模板确实可以包含虚拟或纯虚函数。这是Andrei Alexandresu在“Modern C ++ Design”中使用的,它使用模板和类型列表来实现访问者模式。如果您有兴趣,可以查看代码here in his Loki library

对于大多数标准C ++实现,这很好,因为当实例化模板时,虚函数最终成为单个函数。因此,可以在翻译单元中知道vtable中所需的插槽数量,因此可以生成vtable。

正如您所提到的,您不能拥有虚拟模板成员函数,因为在翻译单元中无法知道vtable插槽的数量。

希望这有帮助!

答案 1 :(得分:8)

模板类中是否允许虚拟(纯和/或普通)虚函数?

是。完全合法。

答案 2 :(得分:7)

考虑模板类是什么 - 它本身不是类,而是编译器可以用来创建类的模板。

因此,没有理由不能在模板类定义中包含虚函数(纯函数或其他函数),因为它本身不会生成任何代码,包括虚拟表。

当我们实际实例化模板类时,例如DataSource<int>,然后编译器只需要为那个选定的类型构建虚拟表,因此它与非模板化类的(纯或其他)虚函数没有任何不同。

答案 3 :(得分:3)

具有虚函数的类模板绝对没问题。但是,不允许在类或模板类中使用虚拟关键字前缀的模板函数。以下将帮助您实现这一目标:

//This is perfectly fine.
template <type T>
class myClass{
     virtual void function() = 0;
};

//This is NOT OK...
template<type T>
class myClass{
      template <type T>
      virtual void function() = 0;
};