Supposed you have a List class, which maintains an unordered list of elements. To increase performance in certain situations, you make a SortedList class that inherits from List, with an improved search algorithm and the necessary modifications to the methods of the List class.
But now you run into a problem. There are some functions you would like to pass a SortedList as a parameter, even though they are only designed to take a List. The obvious solution is using virtual functions in both classes, which would allow SortedList to be casted to List, no problem. However, requiring all uses of List to go through a VFT could be quite a performance hit.
I would like to resolve this problem inside my language, while generally sticking to OOP concepts. These are the soltuions I have come up with:
- Make the methods in classes like List virtual. This reduces the performance hit, but is still quite a serious problem when such basic classes require it. It also fails to solve the problem when a function external to your program requires a non-virtual type that you have inherited from as a parameter.
- Make all methods virtual, as Java does. This could create quite the performance hit, but it would resolve several other issues in the way I plan on using the language.
- Solve it at runtime. Simply allow programmers to cast types as they please and assure them that the correct function will be called, even if not explicitly flagged as virtual. VFTs will be used for methods that are explicitly virtual, and when a cast from an type to its ancestor occurs and some methods are not virtual, regenerate the functions that are not equipped to handle the inherited type. Having multiple copies of functions seems quite wasteful, especially if it is needed often, but this solution gives the programmer the most options and flexibility, especially when dealing with foreign code (under this system foreign code is generally in byte form and can handle this process just fine). It also raises an issue when types are casted to incompatible types and then stored.
- Make incompatible casts create temporary copies, and use these to simulate the previous solution. This can be very wasteful in both time and space. Storing is still an issue with this solution.
- Use either of the above two methods (or both in combination), but allow programmers to explicitly set up certain compatibilities when casting. For example, the SortedList could be temporarily allowed to be used as an unsorted List, and then resorted when the subroutine returns. Storing is still an issue with this solution.
I am open to any recommendations or alternate solutions. In particular, I am interested to hear those who are more familiar with the performance characteristics of VFTs have to say.