为什么C ++,C#和Ada 95中的默认决定是使用静态方法绑定,而不是动态方法绑定。?
实现速度的提升是否值得抽象和可重用性的损失?
答案 0 :(得分:4)
通常,您可以考虑必须为可扩展性设计基类。如果一个成员函数(使用C ++词汇表)不是为了被覆盖而设计的,那么有一个很好的机会而不是覆盖它实际上是不可能的,并且肯定如果没有类设计师的知识就不可能实现它认为是实施细节,如有变更,恕不另行通知。
对两种语言的一些额外考虑(我不知道C#足以写出来):
如果选择不同,Ada 95会与Ada 83产生兼容性问题。考虑到Ada 95的整个对象模型,以不同方式执行它将毫无意义(但您可以认为兼容性是选择对象模型的一个因素)。
对于C ++,性能肯定是一个因素。 你不支付你不使用原则的费用,并且使用C ++作为更好的C 的可能性对它的成功非常有帮助。
答案 1 :(得分:3)
显而易见的答案是因为大多数功能不应该是虚拟的。正如AProgrammer指出的那样,除非明确设计一个函数被覆盖,否则你可能无法在不破坏类不变量的情况下覆盖它(虚拟或非虚拟)。 (例如,当我在Java中工作时,我最终声明了大多数函数final
,这是一个很好的工程问题.C ++和Ada做出了正确的决定:作者必须明确声明该函数被设计为被覆盖
另外,C ++和(我认为)Ada支持值语义。并且值语义不适用于多态性;在Java中,像java.lang.String
这样的类是final
,以便模拟它们的值语义。然而,很多应用程序程序员都不会打扰,因为它不是默认设置。 (以类似的方式,当类是多态的时,太多的C ++程序员忽略了禁止复制和赋值。)
最后,即使一个类是多态的,并且是为继承而设计的,合同仍然是在基类中指定的,并且在合理的情况下是强制执行的。在C ++中,通常,这意味着public
函数不是虚函数,因为它是定义和执行契约的公共函数。
答案 2 :(得分:0)
我不能谈论Ada,但对于C ++来说,设计C ++的两个重要目标是:
虽然这些都不一定要求动态绑定不能被选为默认值,但静态方法绑定(我假设你的意思是非虚拟成员函数)确实似乎更适合这些设计目标
答案 3 :(得分:0)
我会给出迈克尔·伯尔的另外三分之二的答案。
对于Ada而言,该语言适用于系统的编程和小型实时嵌入式设备(例如:导弹和炸弹CPU),这是一个重要的设计目标。也许现在有一些技术可以让动态语言很好地完成这些工作,但是在70年代末期和80年代早期,当语言首次被设计时,这些技术并没有回归。 Ada95当然不能完全偏离原始语言的基本底层设计,不仅仅是C ++可以来自C语言。
话虽如此,Ada和C ++(以及同样的C#也是如此?)提供了一种方法来进行动态方法绑定(“动态调度”),如果你真的想要的话。在两者中都通过指针加入,恕我直言,这是一种容易出错的问题。它也可能使调试变得有些麻烦,因为很难从消息来源中确切地知道调用的内容。所以除非我真的需要它,否则我会避免它。