Topic: static virtual (Was:Multiple Dispatch -- Better Than Item 31?)(http://www.pop.de) (http://www.pop.de)
Author: "J.Barfurth" <techview@bfk-net.de>
Date: 1999/11/25 Raw View
Lorenzo Bettini <bettini@gdn.dsi.unifi.it> schrieb in im Newsbeitrag:
383ADFD4.4F610680@gdn.dsi.unifi.it...
>
> "J.Barfurth" wrote:
> > > 2) Why _can't_ you have a virtual static function? There must be a
good
> > > reason, but I have no clue as to what that good reason is.
>
> In my opinion I think the reason is quite simple:
>
> a static method is not passed "this", and the (run time) type of this is
> used to select a virtual method.
>
> Lorenzo
Generally you have to select a virtual method first, based on the dynamic
type of the object for which the method is invoked, and only then pass it
'this' as an argument. The type of 'this' may be different from both a
pointer to the static type and the dynamic (most derived) type of the
object. All three pointers could in fact have different values when
static_cast'ed to void*. A 'static virtual' method would just be called
without passing the this pointer. This would even save any overhead
necessary to adjust the value needed for 'this'.
As I pointed out before, there are two cases where we already get this kind
of sychronicity: typeid and class-specific operator delete(well sort of ...
in the latter case).
As opposed to typeid, the object expression used to access a static member
is always evaluated anyway. So we needn't introduce any more special cases
into the language to make 'static virtual' work. Moreover, it wouldn't break
existing code and you won't have to pay it's costs if you don't use it.
With the common 'virtual table' implementation of polymorphic dispatch, each
'static virtual' would just introduce another entry in the virtual table.
Another interesting aspect would be whether taking the address of such a
function (referred to through an lvalue)would yield the address of the final
overrider:
struct A { virtual static A* foo(); }
struct B : A { virtual static B* foo(); void bar(); }// note the
covariant return types
A* p = B::foo();
p->foo(); // calls B::foo
A* (*fp)() = &p->foo; // new syntax necessary
fp(); // calls B::foo
// assert(fp == &B::foo); // incompatible types because of covariance
assert(&p->bar == &B::bar); // works without covariance
I guess it should not be too difficult to implement this: For covariant
return types there would be some kind of stub to adjust the return value.
The function pointer could be copied right from the virtual table, so it
would point to that stub. As the pointer types are then unrelated to the
derived one, a conforming program cannot detect this.
An alternative would be to allow a pointer-to-member function to refer to a
static member function, but IMHO the former is much better.
-- J rg Barfurth
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]