【问题标题】:Why do some languages prefer static method binding rather than dynamic? [closed]为什么有些语言更喜欢静态方法绑定而不是动态的? [关闭]
【发布时间】:2011-08-07 15:33:56
【问题描述】:

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

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

【问题讨论】:

  • 是否由于这种默认行为而失去了抽象和可重用性?无论如何你都可以实现它,不是吗?
  • 我不认为执行速度是一个因素;从静态方法调用到动态方法调用的成本差异非常小。我也不同意你的假设,即失去抽象性或可重用性。
  • 在标题中添加了“一些”,试图使其更好地匹配问题(并且少一点争论)。如果框架正确,这实际上是一个很好的问题。
  • @Martin - 可以说,任何感觉需要为作者提供编译指示以请求内联例程的语言(就像 Ada 和 C++ 所做的那样)以消除子例程调用开销可能会吝啬使一切变得动态的“微不足道”的额外成本。
  • @T.E.D. - 也可以争论,特别是。在 Ada 的情况下,允许轻松生成访问子程序 [更多]。正常的静态默认值是“整体推”[类似于宏]和默认情况下使事物动态化之间的一个很好的折衷......动态调用虽然由于它们的间接表而灵活,但也很容易受到攻击,因为该表可能会变成被某人在记忆中跺脚而损坏。

标签: c# c++ ada dynamic-binding late-static-binding


【解决方案1】:

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

两种语言的一些额外注意事项(我对 C# 的了解还不够,无法写这篇文章):

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

  • 对于 C++,性能当然是一个因素。 你不为你不使用的东西付费原则以及将 C++ 用作更好的 C 的可能性对于它的成功非常重要。

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

        【解决方案4】:

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

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

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

        【讨论】:

        • 我已经在用 Ada 编写的实时关键任务系统上使用了动态调度,所以它绝不是不可行的 :)。
        • @NWS - 哦,绝不是。我是原作者的 Ada 解析器生成器 OpenToken 是围绕动态调度构建的。否则,如果您必须有类似大喇叭的 case 声明,它并不会真正让您失去任何东西。
        • @TED,我确定你知道它很实用,只是认为应该指出它在现实世界中也很实用:)
        猜你喜欢
        • 2011-10-20
        • 2011-02-12
        • 1970-01-01
        • 1970-01-01
        • 2011-03-07
        • 1970-01-01
        • 1970-01-01
        • 2011-01-13
        • 1970-01-01
        相关资源
        最近更新 更多