Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C+中的纯虚函数+;11_C++_C++11_Virtual_Pure Virtual_Nullptr - Fatal编程技术网

C++ C+中的纯虚函数+;11

C++ C+中的纯虚函数+;11,c++,c++11,virtual,pure-virtual,nullptr,C++,C++11,Virtual,Pure Virtual,Nullptr,在C++98中,空指针由文本0(或者实际上是任何值为零的常量表达式)表示。在C++11中,我们更喜欢nullptr。但这不适用于纯虚拟函数: struct X { virtual void foo() = nullptr; }; 为什么这不起作用?这不完全有意义吗?这仅仅是一种疏忽吗?它会被修复吗?因为语法说的是0,而不是表达式或其他一些非终端匹配nullptr 一直以来,只有0有效。即使是0L也将是格式错误的,因为它与语法不匹配 编辑 叮当声允许=0x0,=0b0和=00(31.12

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

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

为什么这不起作用?这不完全有意义吗?这仅仅是一种疏忽吗?它会被修复吗?

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

一直以来,只有
0
有效。即使是
0L
也将是格式错误的,因为它与语法不匹配

编辑


叮当声允许
=0x0
=0b0
=00
(31.12.2013)。这是不正确的,当然应该在编译器中修复。

=0
在这里有固定的含义。这里不是一个整数。因此,您不能简单地这样替换它。

没有使用
=0
语法来初始化指针,它只是从语法上指示所提供的
virtual
是纯的


因此,用于声明纯
virtual
s的
=0
语法保持不变。

用于
virtual
函数的
=0
符号并不是字面上的“assign null”,而是一种实际上具有欺骗性的特殊符号:也可以实现纯虚拟函数


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

nullptr的全部要点(或大部分要点)是只能分配给(或用于初始化)指针


在这种情况下,您没有初始化或分配指针,因此在这种情况下您甚至无法使用它。

语法就是这样定义的,如果我们查看
9.2
类成员一节,相关语法如下所示:

[...]
member-declarator:
 declarator virt-specifier-seqopt pure-specifieropt
[...]
pure-specifier:
  = 0
  ^^^
语法明确指出纯说明符是
=0
,而不是整数文本或表达式,这似乎没有留下任何回旋余地。如果我尝试以下事情:

virtual void foo() = 0L;
或:

gcc
告诉我:

错误:“;”之前的纯说明符无效(只允许“=0”)代币

而且,
clang
说:

错误:函数上的初始值设定项看起来不像纯说明符

尽管以下两种方法都适用:

#define bar 0
//...
virtual void foo() = bar;
似乎
clang
允许八进制文字、十六进制文字和二进制文字为零,这是不正确的行为

更新


显然
Visual Studio
接受
NULL
和任何零整数文本,包括
0L
0x0
00
等。。。尽管它不接受
nullptr
,但这并不意味着它是一个指针,或者它必须等于
nullptr


=0
就足够了,这意味着虚拟函数是纯函数

C++11语法在这里只允许
0
(它并不意味着指针)。由于
nullptr
不是
0
,它会失败
NULL
仅在
NULL
定义为
0
时才起作用(有时是这样,但并不总是这样)。只需在此处使用
0
,或者使用以下定义(如果您真的想使用空值,而不是指针)


老实说,即使=0有效,我还是希望
=nullptr
=abstract
语法更好。@TemplateRex:只有
NULL
被定义为单字符文字
0
@stefan:很少是这样,例如一个常见的定义是
(void*)C.@ MattheUM中的0 < /COD>:在C++ <代码> null <代码>必须是整数整数0,<代码>(空隙*)0 < /C> >(如C中)是不允许的。@ ZAC右,因为宏被编译器获得的时间所取代。这里用词不当(尽管已经解释过语法必须是
=0
)是因为人们将
NULL
0
相关联。有人应该复制他的话:“…vtable不是语言要求,只是虚拟方法的一个实现选项…不同的实现(即,没有vtable,没有任何元素存在0)”@Nye感谢您的评论,这样我就可以消除误解了。我告诉他语法上应该是“=0”。我特别没有说“因为事情就是这样”,因为我自己会否决这些答案。为什么不呢?函数通常降级为函数指针,所以我不明白为什么这种语法没有意义。当时他们只是没有可用的
nullptr
关键字。@user2345215:因为
=0
在这个上下文中并不意味着“将null分配给这个指针”,它的意思完全不同。它并不是字面上的意思。但我认为这还是有道理的。它会将函数的地址设置为零指针(如果您真的可以修改它的话),就好像函数什么地方都没有带您一样。但这就是纯虚拟函数的要点。@user2345215:但这不一定是真的。正如Dietmar已经指出的,您可以将函数设为纯虚拟并实现该函数,在这种情况下,vtable中的插槽将包含实际函数的地址。@user2345215:您只知道将在某个位置分配空指针(Jerry指出的情况除外)因为您熟悉平台的虚拟现实实现。C++标准并不规定VTBL必须使用,或者任何关于虚拟如何实现的东西——只有影响应该是什么。通过合并
nullptr
来表示
pure
,标准将隐含地承认平台细节。@ECrownofFire:我认为GCC 4.8在诊断消息方面有了很大改进。FWIW,我们得到
=0#define bar 0
//...
virtual void foo() = bar;
#define VIRTUAL_NULL 0
struct X
{
    virtual void foo() = VIRTUAL_NULL;
};