关于c ++:模板类中是否允许使用纯虚方法?

Are pure virtual methods allowed within a template class?

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

1
2
3
4
5
6
7
8
9
10
11
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;
}

我试过在网上查找它,我所能找到的只是在普通类中不能有虚拟方法(纯方法或其他方法),如:

1
2
3
4
5
6
7
8
9
10
11
12
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++设计"中使用模板和类型列表实现访问者模式的方法。如果你感兴趣的话,你可以在他的loki图书馆里看到代码。

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

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

希望这有帮助!


Are virtual (pure and/or normal) virtual functions allowed within a tempate class?

对。完全合法。


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

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

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


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

1
2
3
4
5
6
7
8
9
10
11
12
//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;
};