Wednesday, September 07, 2005

Why is non-virtual the default in C++ and C#?

Question:
Why are instance methods non-virtual by default in C++ and C# as opposed to Java where the default is virtual?

Answer:
Source of this answer: http://www.artima.com/intv/nonvirtual.html.
I quote the The C# language designer verbatim as he has explained it in quite a lucid manner.

1. Performance:
When people write code in Java, they forget to mark their methods final. Therefore, those methods are virtual. Because they're virtual, they don't perform as well. There's performance overhead associated with being a virtual method.

2. Versioning:
Here is a very real world versioning problem, one that indeed we see now from experience with Java. Whenever they ship a new version of the Java class libraries, breakage occurs. Whenever they introduce a new method in a base class, if someone in a derived class had a method of that same name, that method is now an override—except if it has a different return type, it no longer compiles. The problem is that Java, and also C++, does not capture the intent of the programmer with respect to virtual.

When you say "virtual," you can mean one of two things. If you did not inherit a method of the same signature, then this is a new virtual method. That's one meaning. Otherwise it is an override of an inherited method. That's the other meaning.

From a versioning perspective, it is important that the programmer indicate their intent when they declare a method virtual. In C#, for example, you must explicitly indicate which meaning of virtual you intend. To declare a new virtual method, you just mark it virtual. But to override an existing virtual method, you must say override.

As a result, C# doesn't have the particular versioning problem I described earlier in which we introduce a method in a base class that you already have in a derived class. In your class, you would have declared foo virtual. Now we introduce a new virtual foo. Well, that's fine. Now there are two virtual foos. There are two VTBL slots. The derived foo hides the base foo, but that's fine. The base foo wasn't even there when the derived foo was written, so it's not like there's anything wrong with hiding this new functionality. And things continue to work the way they're supposed to.

0 Comments:

Post a Comment

<< Home