纯虚函数可能没有内联定义.为什么?

Arm*_*yan 59 c++ pure-virtual language-lawyer

纯虚函数是那些虚拟的成员函数,具有pure-specifier(= 0;)

C++ 03第10.4条第2款告诉我们抽象类是什么,作为旁注,以下内容:

[注意:函数声明不能​​同时提供纯指定符和定义-end note] [示例:

struct C {
virtual void f() = 0 { }; // ill-formed
};
Run Code Online (Sandbox Code Playgroud)

- 末端的例子]

对于那些不太熟悉这个问题的人,请注意纯虚函数可以有定义,但上面提到的条款禁止这些定义以内联方式出现(lexically in-class).(对于定义纯虚函数的用法,您可能会看到,例如,这个GotW)

现在,对于所有其他类型和类型的函数,它被允许提供类内定义,并且这种限制乍一看似乎绝对是人为的和莫名其妙的.想到这一点,它似乎在第二次和随后的一瞥:)但我相信如果没有具体原因那么限制将不存在.

我的问题是:有人知道这些具体原因吗?也欢迎良好的猜测.

笔记:

  • MSVC确实允许PVF具有内联定义.所以不要惊讶:)
  • inline此问题中的单词未引用内联关键字.它应该是词汇上的词汇

Che*_*Alf 51

在SO线程中"为什么纯虚函数被0初始化?" Jerry Coffin提供了Bjarne Stroustrup的C++设计与演化,第13.2.3节中的引用,其中我添加了一些我认为相关的部分的重点:

=0选择好奇的语法而不是引入新关键字pure或abstract的明显替代方法,因为当时我看不到接受新关键字的机会.如果我建议纯粹,版本2.0将没有抽象类.给出了更好的语法和抽象类之间的选择,我选择了抽象类.我使用传统的C和C++惯例来使用0表示"不存在",而不是冒着延迟和发生某种纯粹的斗争的风险.该=0语法与适合 我认为一个功能体为功能初始化,并且还与该组的虚拟功能的(简单,但通常是足够的)视图被实现为函数指针的向量.[...]

因此,在选择语法时,Bjarne将函数体视为声明器的一种初始化器部分,并=0作为初始化器的替代形式,表示"无体"(或者用他的话说,"不存在").

按理说,在概念图中,人们不能同时指出"没有"并且有一个身体.

或者,仍然在那个概念图片中,有两个初始化器.

现在,就我的心灵感应力而言,google-foo和软推理都是如此.我猜测没有人有兴趣能够向委员会提出关于解除这种纯粹的语法限制的建议,并跟进所需的所有工作.因此它仍然是这样.

  • 哇... 21票(到目前为止),除非我错过了什么,你说的不是一个字来解决这个问题(这实际上是为什么外线定义是可能的,但内联不是). (16认同)
  • @Tony:很抱歉你不明白我的答案的相关性.我已经尽力了.它不适合你.我不知道怎么说得更清楚.可能我们之间存在沟通鸿沟. (7认同)
  • 有8个小时思考,我看到在`= 0'的网站的狭窄背景下,你所说的是连贯的.我的困惑源于你没有将其与外界定义联系起来或探讨为什么上述思维/逻辑/观点可能不会导致禁止那里的身体定义,或实现用于外面的定义线定义改变了原位定义的思路.这种不一致是问题的核心.如果我们之间仍然存在沟通差距,那么我想我们都做得最好 - 没有造成伤害:-). (5认同)
  • 就像Tony说的那样,似乎你已经回答了这个问题"纯虚函数可能没有定义.为什么?" 而不是"纯虚函数可能没有内联定义(即使它们可能有一个外联定义)."为什么?" (5认同)
  • 报价很强大:) (2认同)

APr*_*mer 8

你不应该对标准化委员会抱有太多信心.并非所有事情都有充分的理由来解释它.有些事情只是因为起初没有人会想到其他事情并且没有人认为改变它是非常重要的(我认为这就是这种情况); 对于足够老的东西,它甚至可能是第一个实现的工件.有些是进化的结果 - 一次有一个很深层次的原因,但原因被删除了,最初的决定没有再次重新考虑(也可能是这里的情况,最初的决定是因为任何定义的纯粹的功能被禁止).有些是不同POV之间谈判的结果,结果缺乏连贯性,但这种缺乏被认为是达成共识所必需的.

  • 所以,是的,我今天打电话给Bjarne,但他没有接.;-) (11认同)
  • @David:在过去的15年里,我打扰了他,可能有6封关于C++的电子邮件.他总是回答,而且非常及时.我怀疑像亚美尼亚这样的问题可能每天都会被数十个人收到他的收件箱中,所以可能无法得到答案.但我不会完全否定这个想法. (2认同)

Ton*_*roy 7

好的猜测......好吧,考虑到这种情况:

  • 声明函数内联并提供一个明确的内联体(在类之外)是合法的,因此显然没有人反对在类中声明的唯一实际含义.
  • 我发现语法中没有引入任何潜在的歧义或冲突,因此没有逻辑上的原因可以将函数定义排除在原位.

我的猜测:在= 0 | { ... }语法形成之后,实现了用于纯虚函数的物体的使用,并且语法根本没有被修改.值得考虑的是,有很多关于语言变化/增强的建议 - 包括那些使这样的事情更合乎逻辑和更一致的建议 - 但是被某人选择并写成正式提案的数量要小得多,而且数量也很少委员会有时间考虑并认为编制供应商准备实施的那些,再次小得多.这样的事情需要一个冠军,也许你是第一个看到问题的人.要了解此过程,请访问http://www2.research.att.com/~bs/evol-issues.html.