2012-01-19 70 views
35

有一次,我肯定你不能这样做,但前几天我正在玩一些代码,它似乎编译和工作。我只是想确认我不幸运。模板类可以有一个纯虚函数 - 我猜这也意味着纯粹的虚方法对于析构函数也是有效的?模板类中是否允许纯虚拟方法?

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

而且这是由于管理虚拟表的可能性来引用所有不同类型的可能类型,所以这种方法将被实例化。

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

无论如何,如果它在那里迷路了,再次提出这个问题: 在临时类中是否允许虚拟(纯的和/或正常的)虚拟函数?

+5

这听起来像你已经想通了这个问题的答案... – 2012-01-19 00:36:15

+3

就像我说的,我对自己发誓,我尝试过并有问题。当它突然开始工作时,我想确保它不仅仅是因为我处于不同的编译器,不同的警告/错误标志等,并且它被定义 - 最好 - 标准是可以的。 – Anthony 2012-01-19 00:40:37

+2

此外,对于它的价值,我无法在网上找到任何明确表示这种或那种方式的内容。比SO更好的地方放置这些信息? – Anthony 2012-01-19 00:41:32

回答

44

类模板确实可以包含虚拟或纯虚函数。 Andrei Alexandresu在“现代C++设计”中采用了这种方法,使用模板和类型列表来实现访问者模式。如果你有兴趣,你可以看到代码here in his Loki library。使用大多数标准的C++实现,这很好,因为当实例化模板时,虚拟函数最终成为一个单一函数。因此,在转换单元内可以知道vtable中所需的槽的数量,因此可以生成vtable。

如上所述,您不能拥有虚拟模板成员函数,因为vtable插槽的数量在翻译单元中是不可知的。

希望这会有所帮助!

6

在临时类中是否允许虚拟(纯粹和/或普通)虚拟函数?

是的。完全合法。

6

想一下模板类是什么 - 它不是类本身,而是编译器可以用来创建类的模板。因此,没有理由不能在模板类定义中包含虚拟函数(纯的或其他),因为它本身不会生成任何代码,包括虚拟表。

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

1

带虚拟功能的类模板绝对没问题。但是,不允许在类或模板类中添加以虚拟关键字为前缀的模板函数。下面将有助于你得到的是:

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