C ++ 11中的纯虚函数

时间:2013-12-31 17:51:33

标签: c++ c++11 virtual pure-virtual nullptr

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

struct X
{
    virtual void foo() = nullptr;
};

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

8 个答案:

答案 0 :(得分:41)

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

只有0才有效。即使0L也会格式不正确,因为它与语法不符。

修改

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

答案 1 :(得分:28)

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

使用各种上下文关键字,允许abstract而不是= nullptr并将abstract作为上下文关键字更有意义。

答案 2 :(得分:17)

这就是如何定义语法,如果我们查看draft C++ standard部分9.2 类成员,相关语法如下:

[...]
member-declarator:
 declarator virt-specifier-seqopt pure-specifieropt
[...]
pure-specifier:
  = 0
  ^^^

语法明确指出纯说明符= 0而不是整数文字表达式,而不是好像留下任何摆动的空间。如果我尝试这样的事情:

virtual void foo() = 0L;

或:

virtual void foo() = NULL ;

gcc告诉我:

  

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

clang说:

  

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

虽然以下两者都有效:

#define bar 0
//...
virtual void foo() = bar;

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

更新

显然Visual Studio接受NULL以及任何零整数字面,包括0L0x000等...虽然它不接受nullptr

答案 3 :(得分:10)

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

答案 4 :(得分:6)

nullptr(或者大多数情况下)的重点是只能分配给(或用于初始化)指针。

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

答案 5 :(得分:5)

= 0语法不用于初始化指针,只是在语法上表明提供的virtual是纯粹的。

因此,声明纯= 0的{​​{1}}语法不变。

答案 6 :(得分:2)

这并不意味着它是一个指针,或者它必须等于nullptr

= 0就足够了,意味着虚函数是纯粹的。

答案 7 :(得分:1)

C ++ 11语法只允许0(并不代表指针)。由于nullptr不是0,它会失败。 NULL仅在NULL被定义为0时才有效(有时是这种情况,但并非总是如此)。只需在这里使用0,或使用以下定义(如果你真的想使用null,当它不是指针时)。

#define VIRTUAL_NULL 0
struct X
{
    virtual void foo() = VIRTUAL_NULL;
};