【问题标题】:pure-specifier on function-definition函数定义上的纯说明符
【发布时间】:2011-02-26 10:25:00
【问题描述】:

在 GCC 上编译时,我得到 error: pure-specifier on function-definition,但当我使用 VS2005 编译相同的代码时却没有。

class Dummy {   
  //error: pure-specifier on function-definition, VS2005 compiles 
  virtual void Process() = 0 {};
};

但是当这个纯虚函数的定义不是内联的时候,它就起作用了:

class Dummy
{
  virtual void Process() = 0;
};
void Dummy::Process()
{} //compiles on both GCC and VS2005

错误是什么意思?为什么我不能内联?如第二个代码示例所示,逃避编译问题是否合法?

【问题讨论】:

    标签: c++ abstract-class pure-virtual


    【解决方案1】:

    好的,我刚刚学到了一些东西。纯虚函数必须声明如下:

    
    class Abstract 
    {
    public:
       virtual void pure_virtual() = 0;
    };
    

    它可能有一个主体,尽管在声明时包含它是非法的。这意味着要拥有一个主体,必须在类之外定义纯虚函数。请注意,即使它有一个主体,该函数仍然必须被派生自Abstract 的任何具体类覆盖。如果需要,他们可以选择显式调用Abstract::pure_virtual()

    详情是here

    【讨论】:

    • 是的,如果您需要的话,应该可以。拥有一个是完全合法的。
    • 但如果有一个主体,它就只是一个虚函数。一个带有body的纯虚函数应该做什么???
    • @Martin 可能什么都没有 - 如果你声明一个纯虚拟析构函数(例如)你必须给它一个主体。
    • @MartinTilsted 不是,请参阅stackoverflow.com/questions/5481941/…
    【解决方案2】:

    C++ 标准,10.4/2:

    函数声明不能​​同时提供纯说明符和定义

    【讨论】:

    • 这不是规范,而是取自注释。
    • @Columbo 好吧,根据 ISO/IEC 指令第 2 部分的第 6.5.1 节,注释根本不应包含权限。虽然这个注释清楚地包含一个,这误导了我。现代的 GCC 和 Clang 仍然不允许这样做,它们是否违反标准?
    • 专业提示:阅读我的答案。注释正确的,但要“证明”这个注释必须显示语法规则。
    【解决方案3】:

    这个语法:

    virtual void Process() = 0 {};
    

    不是合法的 C++,但受 VC++ 支持。究竟为什么标准不允许这样做对我来说从来都不是显而易见的。你的第二个例子是合法的。

    【讨论】:

      【解决方案4】:

      纯虚函数在C++中根据定义在声明中没有定义。

      您的第二个代码块并未避免编译器问题。它按照预期的方式实现了一个纯虚函数。

      要问的问题是,如果您打算使用默认实现,为什么需要将其声明为纯虚拟?

      【讨论】:

      • 纯虚函数可能有定义。想想纯虚拟析构函数——它必须被定义。
      • 请赐教纯虚析构函数的目的?
      • 当您不希望实例化其类并且没有其他 PVF 候选对象时,您可以将析构函数设为纯。非常罕见的要求,我同意。
      • > 如果您打算使用默认实现,为什么需要将其声明为纯虚拟?作为相关代码的作者,我将回答:默认实现是作为派生类的助手提供的。他们应该调用默认实现,但他们需要明确地这样做。这是为了确保调用默认实现是有意识的设计,而不是意外行为。有点像带有转换/构造的“显式”。它没有提供任何新的可能性,但可以帮助避免错误。
      【解决方案5】:

      这在语法上是不允许的 - 可以包含 pure-specifiers 的声明符,即 member-declarator,仅出现在以下声明中不是定义。 [类.mem] :

      成员声明
               attribute-specifier-seqoptdecl-specifier-seq em>optmember-declarator-listopt;
               函数定义
      [...]

      成员声明符列表
               成员声明符
      成员声明符列表 , 成员声明符

      成员声明符
              声明符 virt-specifier-seqoptpure-specifieropt
      声明符大括号或等于初始化器opt
      标识符optattribute-specifier-seqopt: constant-expression

      function-definition的语法不包含pure-specifier,[dcl.fct.def.general]:

      函数定义
           attribute-specifier-seqoptdecl-specifier-seqoptdeclarator virt-specifier-seqoptfunction-body

      【讨论】:

        【解决方案6】:

        您当然可以为纯虚函数提供一个主体。该函数将由该抽象类 vtable 指向。否则,相同的插槽将指向编译器特定的陷阱函数,例如 GCC 的 __cxa_pure_virtual。标准中当然没有这方面的内容。

        【讨论】:

          猜你喜欢
          • 2017-06-08
          • 1970-01-01
          • 2014-01-17
          • 2016-01-06
          • 2020-06-17
          • 2012-03-14
          • 1970-01-01
          • 2017-01-15
          • 2015-06-28
          相关资源
          最近更新 更多