2

为什么 C++、C# 和 Ada 95 中的默认决定是使用静态方法绑定,而不是动态方法绑定。?

实现速度的提高是否值得抽象和可重用性的损失?

4

4 回答 4

4

一般来说,您可以考虑必须设计基类以实现可扩展性。如果成员函数(使用 C++ 词汇表)没有被设计为被覆盖,那么很有可能在实践中不可能覆盖它,并且如果不知道类设计器是什么,肯定是不可能的think 是实施细节,如有更改,恕不另行通知。

两种语言的一些额外注意事项(我对 C# 的了解不够多,无法写出来):

  • 如果选择不同,Ada 95 将与 Ada 83 存在兼容性问题。并且考虑到 Ada 95 的整个对象模型,以不同的方式做是没有意义的(但您可以认为兼容性是选择对象模型的一个因素)。

  • 对于 C++,性能当然是一个因素。您无需为不使用的原则付费,并且可以像使用更好的 C 一样使用 C++,这对它成功非常重要。

于 2011-04-18T06:53:12.653 回答
3

显而易见的答案是因为大多数功能不应该是虚拟的。正如 AProgrammer 所指出的,除非一个函数被明确地设计为被覆盖,否则你可能无法在不破坏类不变量的情况下覆盖它(虚拟或非虚拟)。(例如,当我在 Java 中工作时,我最终声明了大多数函数final,这是一个好的工程问题。C++ 和 Ada 做出了正确的决定:作者必须明确声明该函数旨在被覆盖。

此外,C++ 和(我认为)Ada 支持值语义。并且值语义不适用于多态性;在 Java 中,像java.lang.Stringare这样的类是final为了模拟它们的值语义。然而,对于许多应用程序程序员来说,不要打扰,因为它不是默认设置。(以类似的方式,当类是多态的时,太多的 C++ 程序员忽略了禁止复制和赋值。)

最后,即使一个类是多态的,并且是为继承而设计的,契约仍然是指定的,并且只要是合理的,在基类中强制执行。在 C++ 中,这通常意味着public函数不是虚拟的,因为定义和执行合约的是公共函数。

于 2011-04-18T07:59:59.573 回答
0

我不能谈论 Ada,但对于 C++,C++ 设计的两个重要目标是:

  • 向后兼容 C
  • 您不应该为您不使用的功能支付任何费用(尽可能)

虽然这些都不一定表明动态绑定不能被选为默认值,但静态方法绑定(我假设您的意思是非虚拟成员函数)似乎确实“更适合”这些设计目标。

于 2011-04-18T07:02:24.890 回答
0

我将给出迈克尔伯尔答案的另外三分之二之一。

对于 Ada 来说,一个重要的设计目标是该语言适用于系统编程并在小型实时嵌入式设备(例如:导弹和炸弹 CPU)上使用。也许现在有一些技术可以让动态语言很好地完成这些事情,但是在 70 年代末和 80 年代初首次设计该语言时肯定不会出现这种情况。Ada95 当然不能从根本上偏离原始语言的基本底层设计,就像 C++ 不能偏离 C 一样。

话虽如此,如果您真的想要的话,Ada 和 C++(当然还有 C#?)都提供了一种进行动态方法绑定(“动态调度”)的方法。在两者中,它都是通过指针访问的,恕我直言,这有点容易出错。它也可能使调试变得有点痛苦,因为很难仅从源代码中准确地判断出什么被调用。所以除非我真的需要它,否则我会避免它。

于 2011-04-18T13:30:53.827 回答