2

Why is the default decision in C++, C#, and Ada 95 to use static method binding, rather than dynamic method binding.?

Is the gain in implementation speed worth the loss in abstraction and re-usability?

T.E.D.
  • 44,016
  • 10
  • 73
  • 134
Glove
  • 960
  • 6
  • 17
  • 30
  • Is abstraction and re-usability lost due to this default behavior? You can achieve it anyway can't you? – Shamim Hafiz - MSFT Apr 18 '11 at 06:47
  • I don't think implementation speed is a factor; the difference in cost from static to dynamic method call is exceedingly trivial. I also don't agree with your supposition that there is a loss of abstraction or re-usability. – Martin York Apr 18 '11 at 06:49
  • 1
    Added "some" to the title in an attempt to make it match the question better (and be a bit less argumentative). It actually is a good question to ask, if framed right. – T.E.D. Apr 18 '11 at 13:08
  • @Martin - It could be argued that any language that feels the need to supply pragmas for authors to request routines be inlined (as both Ada and C++ do) to remove subroutine call overhead is likely to begrudge the "trivial" extra cost for making everything dynamic. – T.E.D. Apr 18 '11 at 13:43
  • @T.E.D. -- It could also be argued, esp. in the case of Ada, to allow for Access-to-Subprograms to [more] easily be generated. The normal static default is a good compromise between "shove it in whole" [macro-like] and making things dynamic by default... dynamic-calls, while flexible due to their indirection-tables, are also vulnerable because that table might become damaged by someone stomping around in memory. – Shark8 Apr 26 '11 at 21:06

4 Answers4

4

In general, you can consider that you have todesign the base class for extensibility. If a member function (to use the C++ vocabulary) isn't designed to be overridden, there is a good chance than overriding it will in practice not be possible and for sure it won't it be possible without knowledge of what the class designer think is implementation details and will change without giving you prior notice.

Some additional considerations for two languages (I don't know C# enough to write about it):

  • Ada 95 would have had compatibility issues with Ada 83 if the choice was different. And considering the whole object model of Ada 95, doing it differently would have make no sense (but you can consider that compatibility was a factor in the choice of the object model).

  • For C++, performance was certainly a factor. The you don't pay for what you don't use principle and the possibility to use C++ just as a better C was quite instrumental in its success.

AProgrammer
  • 51,233
  • 8
  • 91
  • 143
3

The obvious answer is because most functions shouldn't be virtual. As AProgrammer points out, unless a function has been designed explicitly to be overridden, you probably can't override it (virtual or not) without breaking class invariants. (When I work in Java, for example, I end up declaring most functions final, as a matter of good engineering. C++ and Ada make the right decision: the author must explicitly state that the function is designed to be overridden.

Also, C++ and (I think) Ada support value semantics. And value semantics doesn't work well with polymorphism; in Java, classes like java.lang.String are final, in order to simulate value semantics for them. Far to many applications programmers, however, don't bother, since it's not the default. (In a similar manner, far too many C++ programmers omit to inhibit copy and assignment when the class is polymorphic.)

Finally, even when a class is polymorphic, and designed for inheritance, the contract is still specified, and in so far as is reasonable, enforced, in the base class. In C++, typically, this means that public functions are not virtual, since it is the public functions which define and enforce the contract.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
0

I can't speak about Ada, but for C++ two important goals for the design of C++ were:

  • backwards compatibility with C
  • you should pay nothing (to the extent possible) for features that you don't use

While neither of these would necessarily dictate that dynamic binding couldn't have been chosen to be the default, having static method binding (I assume you mean non-virtual member functions) does seem to 'fit' better with these design goals.

Michael Burr
  • 333,147
  • 50
  • 533
  • 760
0

I'll give one of the other two thirds of Michael Burr's answer.

For Ada it was an important design goal that the language be suitable for system's programming and use on small realtime embedded devices (eg: missile and bomb CPUs). Perhaps there are now techniques that would allow dynamic languages to do such things well, but there certianly weren't back in the late 70's and early 80's when the language was first being designed. Ada95 of course could not radically deviate from the orginal language's basic underlying design, any more than C++ could from C.

That being said, both Ada and C++ (and certianly C# as well?) provide a way to do dynamic method binding ("dynamic dispatch") if you really want it. In both it is accesed via pointers, which IMHO are kind of error-prone. It can also make things a bit of a pain to debug, as it is tough to tell from sources alone exactly what is getting called. So I avoid it unless I really need it.

T.E.D.
  • 44,016
  • 10
  • 73
  • 134
  • I Have used dynamic dispatching on real time mission critical systems written in Ada, so its my no means unworkable :) . – NWS Apr 18 '11 at 14:06
  • @NWS - Oh, by no means. OpenToken, the Ada parser-generator I was the original author for, is built around dynamic dispatch. If you'd otherwise have to have something like a big-honking `case` statement, it doesn't really lose you much of anything. – T.E.D. Apr 18 '11 at 18:32
  • @TED, I was sure you knew it was practical, jus thought that it should be pointed out that it is practical in the real world as well :) – NWS Apr 19 '11 at 11:38