我们总是将纯虚函数声明为:
virtual void fun () = 0 ;
即,始终将其分配为0。
我了解的是,这是将此函数的vtable条目初始化为NULL,此处的任何其他值都会导致编译时错误。这种理解正确与否?
virtual void func() = 100;
我们总是将纯虚函数声明为:
virtual void fun () = 0 ;
即,始终将其分配为0。
我了解的是,这是将此函数的vtable条目初始化为NULL,此处的任何其他值都会导致编译时错误。这种理解正确与否?
virtual void func() = 100;
Answers:
原因=0
是Bjarne Stroustrup认为在实现该功能时,他不能在C ++社区之外获得另一个关键字,例如“ pure”。这在他的书《 C ++的设计和演变》第13.2.3节中进行了描述:
之所以选择= 0好奇的语法是因为……当时我还没有机会接受新的关键字。
他还明确指出,这无需将vtable条目设置为NULL,并且这样做不是实现纯虚拟功能的最佳方法。
与大多数有关C ++设计的“为什么”问题一样,首先要看的是Bjarne Stroustrup 1撰写的《 C ++的设计和演进》:
=0
选择好奇的语法而不是引入新关键字的明显替代方法,pure
或者abstract
因为当时我看不到接受新关键字的机会。如果我建议的话pure
,2.0版将没有抽象类。在更好的语法和抽象类之间做出选择之后,我选择了抽象类。我没有冒延迟和招致某些争执的风险pure
,而是使用了传统的C和C ++约定,即使用0表示“不在那儿”。该=0
语法与配合我认为一个功能体为功能也与所述一组虚拟功能的(简单,但通常是足够的)视图被实现为函数指针的向量初始化。[...]
1 §13.2.3语法
C ++标准的9.2节提供了类成员的语法。它包括此生产:
pure-specifier:
= 0
价值没有什么特别的。“ = 0”只是表示“此函数是纯虚函数”的语法。它与初始化,空指针或数字零无关,尽管与这些东西的相似之处可能具有助记符。
= 0
您还想知道什么?这将与询问为什么用{}包裹函数体是相同的,答案是,因为这是C ++语法定义的。
C ++总是回避引入新的关键字,因为新的保留字破坏了使用这些字作为标识符的旧程序。通常,它尽可能地尊重旧代码是该语言的优势之一。
在= 0
可能确实已选择语法,因为它酷似设置虚函数表条目0
,但是这纯粹是象征性的。(大多数编译器将此类vtable条目分配给存根,该存根在中止程序之前会产生错误。)之所以选择该语法,是因为该语法之前没有被使用过,并且节省了引入新关键字的可能性。
pure
在我的书中,使用关键字非常有用。无论如何,了解原理是一件好事。
#define pure = 0
。
该= 0
声明了一个纯虚函数。
可以理解的是,这是将此函数的vtable条目初始化为NULL,此处的任何其他值都会导致编译时错误
我认为那不是真的。这只是特殊的语法。vtable是实现定义的。没有人说过,纯成员的vtable条目在构造时实际上必须清零(尽管大多数编译器都处理类似的vtable)。
= 0
是使整个类抽象化并禁止对纯函数的虚拟调用。使用定义(如果已提供)时,非虚拟调用仍然可以正常执行。
__cxa_pure_virtual
arobenko.gitbooks.io/bare_metal_cpp/content/compiler_output/…代替了Base :: f()
好吧,您也可以初始化vtable条目以指向实际功能”
virtual void fun()
{
//dostuff()
}
看起来很直观,可以将vtable条目定义为不指向任何地方(0)或指向函数。让您为其指定自己的值可能会导致它指向垃圾而不是函数。但这就是为什么允许“ = 0”而不允许“ = 1”的原因。我怀疑尼尔·巴特沃思(Neil Butterworth)为何使用“ = 0”是正确的