为什么纯虚函数初始化为0?

时间:2010-01-28 17:48:38

标签: c++ abstract-class pure-virtual

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

virtual void fun () = 0 ;

即,它总是被赋值为0。

我的理解是,这是将此函数的vtable条目初始化为NULL,此处的任何其他值都会导致编译时错误。这种理解是否正确?

11 个答案:

答案 0 :(得分:157)

使用=0的原因是Bjarne Stroustrup不认为他可以获得另一个关键字,例如在实现该功能时通过C ++社区的“纯粹”。这在他的书The Design & Evolution of C++,第13.2.3节:

中有所描述
  

选择了好奇的= 0语法......   因为当时我没有看到任何机会   获得新关键字。

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

答案 1 :(得分:76)

与大多数关于C ++设计的“为什么”问题一样,首先要看的是 C ++的设计和演变,作者:Bjarne Stroustrup 1

  

选择了好奇的=0语法   在明显的替代方案   引入新关键字pure或   abstract因为在我看到的时候   没有机会获得新的关键字   公认。如果我建议pure,   版本2.0将没有发货   抽象类。给出了一个选择   在更好的语法和抽象之间   我选择了抽象类。   而不是冒险延迟和   引发某些争斗   pure,我使用了传统的C和C ++   使用0表示的惯例   “不在那里。” =0语法符合   我认为一个功能体是   函数的初始化器也用   (简单但通常足够)   视图的虚拟功能集   被实现为一个向量   函数指针。 [...]

1 §13.2.3语法

答案 2 :(得分:29)

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

pure-specifier:
    = 0

价值没什么特别之处。 “= 0”只是说“此函数是纯虚拟”的语法。它与初始化或空指针或数值零无关,尽管与这些事物的相似性可能具有助记值。

答案 3 :(得分:19)

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

答案 4 :(得分:15)

C ++总是避免引入新的关键词,因为新的保留词会破坏使用这些词作为标识符的旧程序。它通常被视为语言的优势之一,它尽可能地尊重旧代码。

可能确实选择了= 0语法,因为它类似于将vtable条目设置为0,但这纯粹是象征性的。 (大多数编译器将这样的vtable条目分配给存根,该存根在中止程序之前发出错误。)语法主要被选择,因为它之前没有用于任何东西,它保存了引入新关键字。

答案 5 :(得分:11)

C ++必须有办法区分纯虚函数和普通虚函数的声明。他们选择使用= 0语法。他们可以通过添加纯关键字轻松完成相同的操作。但是C ++非常不愿意添加新的关键字,而更喜欢使用其他机制来引入功能。

答案 6 :(得分:7)

在这种情况下,没有任何东西被“初始化”或“分配”为零。 = 0只是一个由=0令牌组成的句法结构,与初始化或赋值完全无关。

它与“vtable”中的任何实际值无关。 C ++语言没有“vtable”或类似的任何概念。各种“vtable”只不过是具体实现的细节。

答案 7 :(得分:3)

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

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

答案 8 :(得分:2)

我认为这只是C ++语法的一部分。我认为对于给定的特定二进制格式,编译器如何实际实现这一点并不存在任何限制。你可能认为早期的C ++编译器是正确的。

答案 9 :(得分:2)

= 0声明纯虚函数

  

可以理解的是,这是将此函数的vtable条目初始化为NULL,此处的任何其他值都会导致编译时错误

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

答案 10 :(得分:1)

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

 virtual void fun()
 {
     //dostuff()
 }

直观地说,vtable条目可以定义为指向任何地方(0)或函数。让你为它指定自己的值可能会导致它指向垃圾而不是函数。但这就是为什么“= 0”被允许而“= 1”不被允许的原因。我怀疑Neil Butterworth对于为什么“= 0”被使用是正确的