关于c ++:为什么纯虚函数初始化为0?

Why is a pure virtual function initialized by 0?

我们总是声明纯虚函数为:

1
virtual void fun () = 0 ;

也就是说,它总是被分配到0。

我理解的是,这是为了将此函数的vtable项初始化为空,而这里的任何其他值都会导致编译时错误。这种理解正确与否?


使用EDOCX1 4的原因是Bjarne Stroustrup认为他不能获得另一个关键字,例如在实现该功能时C++社区中的"纯"。这在他的书《C++设计与进化》第132.3节中有描述:

The curious =0 syntax was chosen ...
because at the time I saw no chance of
getting a new keyword accepted.

他还明确指出,这不需要将vtable项设置为空,这样做并不是实现纯虚拟函数的最佳方法。


与大多数关于C++设计的"为什么"有关的问题,首先要看的是C++的设计和演化,由BjARNE StruouTrpU1:

The curious =0 syntax was chosen
over the obvious alternative of
introducing a new keyword pure or
abstract because at the time I saw
no chance of getting a new keyword
accepted. Had I suggested pure,
Release 2.0 would have shipped without
abstract classes. Given a choice
between a nicer syntax and abstract
classes, I chose abstract classes.
Rather than risking delay and
incurring the certain fights over
pure, I used the tradition C and C++
convention of using 0 to represent
"not there." The =0 syntax fits with
my view that a function body is the
initializer for a function also with
the (simplistic, but usually adequate)
view of the set of virtual functions
being implemented as a vector of
function pointers. [ ... ]

1§13.2.3语法


C++标准的第9.2节给出类成员的语法。它包括这个产品:

1
2
pure-specifier:
    = 0

价值没有什么特别的。"=0"只是表示"这个函数是纯虚拟的"的语法,它与初始化、空指针或数值0无关,尽管与这些东西的相似性可能有助于记忆。


我不确定这背后是否有任何意义。它只是语言的语法。


由于新的保留词打破了使用这些单词的标识符的旧程序,所以C++一直回避引入新的关键字。它常常被视为语言的优势之一,因为它尽可能尊重旧代码。

可能确实选择了= 0语法,因为它类似于为0设置vtable条目,但这纯粹是符号。(大多数编译器将这样的vtable条目分配给一个存根,该存根在中止程序之前会发出一个错误。)之所以选择语法,主要是因为它以前什么都没有使用过,并且它保存了引入一个新关键字的内容。


C++必须有一种方法来区分一个纯虚函数和一个正常虚函数的声明。他们选择使用= 0语法。他们只需添加一个纯关键字就可以轻松地做到这一点。但是C++很不愿意添加新的关键字,并且喜欢使用其他机制来引入特征。


在这种情况下,没有"初始化"或"分配"零。= 0只是一个由=0标记组成的语法结构,它与初始化或赋值完全没有关系。

它与"vtable"中的任何实际值都没有关系。C++语言没有"VTABLE"的概念,也没有类似的概念。各种"vtables"只不过是具体实现的细节。


我记得我读到过这样一段话,有趣的语法的理由是它比引入另一个关键字来做同样的事情更容易(在标准接受方面)。

我相信Bjarne Stroustrup在C++的设计和进化中提到了这一点。


= 0声明纯虚拟函数。

What is understand is that this is to initialize the vtable entry for this function to NULL and any other value here results in compile time error

我不认为那是真的。这只是特殊的语法。vtable是实现定义的。没有人说纯成员的vtable条目实际上必须在构造时归零(尽管大多数编译器处理vtables的方式类似)。


我认为这只是C++语法的一部分。我认为对于编译器如何为特定的二进制格式实现这一点没有任何限制。你假设对早期C++编译器可能是正确的。


那么,您也可以初始化vtable条目以指向实际函数。"

1
2
3
4
 virtual void fun()
 {
     //dostuff()
 }

似乎很直观,vtable条目既可以定义为指向无处(0),也可以定义为指向函数。允许您为它指定自己的值可能会导致它指向垃圾,而不是指向函数。但这就是为什么"=0"是允许的,而"=1"是不允许的。我怀疑尼尔·巴特沃斯关于"=0"被使用的原因是正确的。