38

在 GCC 上编译时出现错误: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

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

4

6 回答 6

36

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


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

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

详情在这里

于 2010-06-01T15:58:57.927 回答
20

C++ 标准,10.4/2:

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

于 2010-06-01T16:03:16.143 回答
13

这个语法:

virtual void Process() = 0 {};

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

于 2010-06-01T16:00:10.483 回答
4

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

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

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

于 2010-06-01T16:01:42.540 回答
3

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

成员声明attribute-specifier-seq opt decl-specifier-seq opt member-declarator-list opt function-definition          [...]
          ;
         

member-declarator-list :
         member-declarator
         member-declarator-list , member-declarator

member-declarator :
         declarator virt-specifier-seq opt 纯说明符opt
         declarator 大括号或等式初始化器opt
         identifier opt attribute-specifier-seq opt : 常量表达式

函数定义的语法不包括纯说明符[dcl.fct.def.general]:

函数定义
     attribute-specifier-seq opt decl-specifier-seq opt declarator virt-specifier-seq opt function-body

于 2015-04-19T19:50:38.120 回答
0

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

于 2010-06-01T16:09:10.307 回答