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

Are pure virtual methods allowed within a template class?

本文关键字:许使用 虚拟 方法 是否      更新时间:2023-10-16

以前,我确信你做不到这一点,但前几天我在玩一些代码,它似乎可以编译并工作。我只是想证明我不仅仅是运气好。模板类可以有一个纯虚拟函数吗?我想这也意味着纯虚拟方法对析构函数也是有效的?

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类中是否允许使用虚拟(纯和/或普通)虚拟函数?

类模板确实可以包含虚拟或纯虚拟函数。Andrei Alexandresu在"现代C++设计"中采用了这种方法,使用模板和类型列表来实现访问者模式。如果你感兴趣的话,你可以在他的洛基图书馆里看到代码。

对于大多数标准C++实现,这是可以的,因为当模板被实例化时,虚拟函数最终成为一个单独的函数。因此,在转换单元内可以知道vtable中所需的槽的数量,因此可以生成vtable。

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

希望这能有所帮助!

tempate类中是否允许使用虚拟(纯和/或普通)虚拟函数?

是的。完全合法。

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

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

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

一个带有虚拟函数的class模板绝对不错。但是,不允许在类或模板类中使用前缀为virtual关键字的模板函数。以下将帮助您获得:

//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;
};