函数定义上的纯说明符
Posted
技术标签:
【中文标题】函数定义上的纯说明符【英文标题】: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
错误是什么意思?为什么我不能内联?如第二个代码示例所示,逃避编译问题是否合法?
【问题讨论】:
【参考方案1】:好的,我刚刚学到了一些东西。纯虚函数必须声明如下:
class Abstract
public:
virtual void pure_virtual() = 0;
;
它可能有一个主体,尽管在声明时包含它是非法的。这意味着要拥有一个主体,必须在类之外定义纯虚函数。请注意,即使它有一个主体,该函数仍然必须被派生自Abstract
的任何具体类覆盖。如果需要,他们可以选择显式调用Abstract::pure_virtual()
。
详情是here。
【讨论】:
是的,如果您需要的话,应该可以。拥有一个是完全合法的。 但如果有一个主体,它就只是一个虚函数。一个带有body的纯虚函数应该做什么??? @Martin 可能什么都没有 - 如果你声明一个纯虚拟析构函数(例如)你必须给它一个主体。 @MartinTilsted 不是,请参阅***.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
。标准中当然没有这方面的内容。
【讨论】:
以上是关于函数定义上的纯说明符的主要内容,如果未能解决你的问题,请参考以下文章