Topic: remove the virtuality-gene in the middle of an inheritance tree


Author: esap@cs.tut.fi (Pulkkinen Esa)
Date: 1996/06/22
Raw View

>In article <2xbuioukf2.fsf_-_@obelix.mpi-sb.mpg.de> you wrote:
>> I would very mouch appreciate some handy example for the _need_ to
>> remove the virtuality `gene' inside a derivation tree! I understand

Martin D Kealey  <martin@kcbbs.gen.nz> wrote:
>I have a *real* example in some code I'm working on right now.  The basic
>idea is a base class that services incoming events through a common
>interface.  These are overridden by successively more specific handlers,
>mapping the events at each protocol level to calls.  The point is, once
>a level of protocol has been dealt with, it should not be meddled with
>by someone overriding the lower level virtual function.

I would suggest using aggregation to model different levels of event
handlers. (The less specific handler aggregates the more specific handler that
uses an abstract interface to get back to the more specific handler).
Apart from the fact it doesn't need a language extension, it also provides
more dynamic structure and allows (even dynamic) configuration of participating
handlers.

>Here is an example:
{Removed a class 'EndPoint' with a static function forwarding events to
an abstract virtual function 'handle_poll_result'}

>    class Receiver : EndPoint {
>        virtual void handle_data( string data ) = 0;
>        virtual void handle_eof() = 0;
>
>        /*final*/ void handle_poll_result( iostream file, int events_bitmask )
>    };

Why should you use the same class for both the interface to the higher
level handler and the lower level handler implementation? If you separate them,
(making the interface between the lower and higher level handlers fully
abstract) you can control what functions you want to prevent from being
accidentally overridden by excluding them from the higher level handler's
interface. With multiple inheritance (and aggregation to connect different
levels of handlers), this gives exactly what you want.

I'd assume efficiency is the main (only?) reason that for example Java has
this feature of allowing the user to remove virtualness of a virtual
function. But I have yet to see the efficiency gains of the feature.
Even though O-O programs use lots of virtual functions, my experience
is that in most programs the amount of time used by the virtual
function calls is neglible, and with careful design, you can always
reduce this cost further if needed.

Also, I think the feature is dangerous (in terms of design). It encourages
the programmer to define lots of virtual functions and later in derived
class finalize the functions so no-one can override them "to allow
efficient calls to the virtual functions when its known to be unnecessary".
But the resulting derived class is unusable for implementation reuse,
since most often you will want to override some virtual functions
(for example to forward the request to some other object), but would
want to retain the implementation. And usually you can't know until
you actually implement the derived class which functions you want to
override. (Note the same problem applies to normal non-virtual functions).
At worst the feature can lead to interface-implementation pairs where
you can't reuse the implementation since all functions have been declared
final in terms of efficiency and you have to reimplement the whole
interface (assuming you can't or don't want to change the interface)
in order to support some small change in the functionality.
--
   Esa Pulkkinen                        | C++ programmers do it virtually
   E-Mail:  esap@cs.tut.fi              | everywhere with a class, resulting
   WWW   :  http://www.cs.tut.fi/~esap/ | in multiple inheritance.






[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]