C++ 11中的纯虚函数

fre*_*low 35 c++ virtual pure-virtual nullptr c++11

在C++ 98中,空指针由文字表示0(或实际上是值为零的任何常量表达式).在C++ 11中,我们更喜欢nullptr.但这对纯虚函数不起作用:

struct X
{
    virtual void foo() = nullptr;
};
Run Code Online (Sandbox Code Playgroud)

为什么这不起作用?这不是很有意义吗?这只是一个疏忽吗?它会被修复吗?

Joh*_*itb 43

因为语法说0,不是表达式或其他一些非终端匹配nullptr.

0一直只有工作.即使0L是不正确的,因为它与语法不匹配.

编辑

铛允许= 0x0,= 0b0= 00(2013年12月31日).这是不正确的,当然应该在编译器中修复.

  • @TemplateRex:只将`NULL`定义为单​​个字符文字`0`. (3认同)

Die*_*ühl 28

函数的= 0符号virtual并非字面上的"赋值为空",而是一种实际上具有欺骗性的特殊符号:也可以实现纯虚函数.

使用各种上下文关键字,允许abstract而不是= nullptr并且abstract成为上下文关键字会更有意义.

  • FWIW,我们得到`= 0`而不是'abstract`的原因(简称)Bjarne认为他不能在历史的曙光中推动另一个关键词超越C++委员会.我认为这是他个人遗憾的名单,虽然是一个小的遗憾. (3认同)

Sha*_*our 17

这就是如何定义语法,如果我们查看草案C++标准部分的9.2 Class成员,相关的语法如下:

[...]
member-declarator:
 declarator virt-specifier-seqopt pure-specifieropt
[...]
pure-specifier:
  = 0
  ^^^
Run Code Online (Sandbox Code Playgroud)

语法特别指出pure-specifier= 0而不是整数文字表达式,似乎没有留下任何摆动空间.如果我尝试这样的事情:

virtual void foo() = 0L;
Run Code Online (Sandbox Code Playgroud)

要么:

virtual void foo() = NULL ;
Run Code Online (Sandbox Code Playgroud)

gcc 告诉我:

错误:在';'之前无效的纯说明符(仅允许'= 0')代币

clang说:

错误:函数初始化器看起来不像纯粹的说明符

虽然以下两者都有效:

#define bar 0
//...
virtual void foo() = bar;
Run Code Online (Sandbox Code Playgroud)

它似乎也clang允许八进制文字,十六进制文字二进制文字零,这是不正确的行为.

更新

显然Visual Studio接受NULL任何零整数文字包括0L,0x0,00等......虽然它不接受nullptr.

  • 等等,gcc实际上有比clang更好的错误信息吗? (7认同)
  • @ECrownofFire:我认为GCC 4.8在诊断消息方面有很大改进. (2认同)

use*_*215 10

= 0那里有一个固定的含义.那里并不是真正的整数零.因此,您不能简单地替换它.


Jer*_*fin 6

nullptr无论如何(或大多数点)的全部要点是只能分配给(或用于初始化)指针.

在这种情况下,您没有初始化或分配指针,因此在这种情况下您可以使用它甚至没有意义.

  • @ user2345215:您只知道将在某处分配空指针(Jerry指出的情况除外),因为您熟悉平台的虚拟实现.C++标准没有规定必须使用vtbl,或者任何关于*how*virtual的实现 - 只有效果应该是什么.通过将`nullptr`混淆以表示`pure`,标准将隐含地承认平台细节. (2认同)

Joh*_*ing 5

所述= 0语法不使用初始化一个指针,它只是在句法指示提供virtual是纯的.

因此= 0,声明纯virtuals 的语法不变.