【问题标题】:Are pure virtual methods allowed within a template class?模板类中是否允许纯虚方法?
【发布时间】:2012-02-13 17:29:54
【问题描述】:

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

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

这是由于无法管理虚拟表来引用此方法将要实例化的所有不同类型的可能类型。

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

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

【问题讨论】:

  • 听起来你已经找到了答案……
  • 就像我说的,我向自己发誓我之前尝试过但遇到了问题。当它突然起作用时,我想确保它不仅仅是因为我使用不同的编译器、不同的警告/错误标志等,而且它被定义——最好是——按照标准是可以的。
  • 另外,就其价值而言,我在网上找不到任何可以明确表示某种方式的东西。还有什么比 SO 更适合放置这些信息的地方?

标签: c++ templates virtual


【解决方案1】:

类模板确实可以包含虚函数或纯虚函数。 Andrei Alexandresu 在“现代 C++ 设计”中采用了这一点,以使用模板和类型列表来实现访问者模式。有兴趣可以看代码here in his Loki library

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

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

希望这会有所帮助!

【讨论】:

    【解决方案2】:

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

    是的。完全合法。

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

        【解决方案4】:

        带有虚函数的类模板绝对没问题。但是,不允许在类或模板类中带有前缀 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;
        };
        

        【讨论】:

          猜你喜欢
          • 2016-10-14
          • 2019-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-07-12
          • 2012-11-04
          • 2015-12-08
          • 2017-08-03
          • 1970-01-01
          相关资源
          最近更新 更多