|
![](/i/fill.gif) |
Warp wrote:
> Darren New <dne### [at] san rr com> wrote:
>> For something managed, I think that would be the wrong way to implement MI.
>> It's still just one object, even if it inherits data and code from multiple
>> classes. For example, Python has MI and doesn't have pointers into the
>> middle of objects.
>
> That sounds like it would be somewhat inefficient. If the pointer always
> points to the beginning of the object, then it would always need to resolve
> the offset to the members it wants every time it wants to access them
> (because in a multiple-inherited object the members of the base class you
> want do not necessarily start from the beginning of the object the pointer
> is pointing to, but could start from anywhere).
Yep. Python is very dynamic. You can, for example, turn
xyz.pdq = 5
into a function call on xyz that passes the string "pdq" as the first
argument and 5 as the second. It's not supposed to be efficient. It's
supposed to be expressive. :-)
>> You could also do it as a sort of "automatic delegation", where each of the
>> multiple parent classes is represented as a separate object on the heap, for
>> example, and the child class delegates all the non-overridden calls to the
>> parent class.
>
> That sounds like you would need several steps of indirection in order
> to access a base class member using a derived class pointer.
Yep. Either that or, as I said, have the JIT do it the first time.
> And checks
> for this would need to be done for *all* accesses, even in situations where
> there's no inheritance at all (because the code which tries to access the
> object through the pointer cannot know if the object it was given was a
> derived object or not, without always checking).
Well, what I meant was that if you have Alpha::Hello() and Beta::There() and
you create a Gamma that inherits from both, you could actually copy the code
of Alpha::Hello and Beta::There into Gamma, adjusting the offsets of local
variables as you go. With clever vtable layout, you could have Alpha::Hello
and Gamma::Hello at the same offset in the vtable, and the same with
Beta:There and Gamma::There. (That's what Meyer invented for Eiffel.)
> It's more efficient when code which handles objects of a certain type
> doesn't need to perform any checks to see if the object is really of that
> precise type, or whether it's some inherited type. From the point of view
> of that code the object looks exactly like if it was exactly of that
> precise type (all the member offsets are always the same) regardless of
> what the actual type of the object is.
Yes. But that's not really the problem. The problem is that it's *machine*
code you're dealing with in C++, where all the information about what local
variables you're using has been lost. In the CIL, I have no trouble taking
a method and making every reference to "the first member variable" and
changing it to "the third member variable". And then you JIT that and you
get equally efficient code.
> Well, the Java people added their crippled version of templates to the
> language regardless of all the arguments why templates are bad, so maybe
> there's hope that MI will also be added, regardless of all the arguments
> why it's bad.
Well, not templates as such. Nothing near as useful. Just generics, using
the same awful C++ syntax. :-)
> (It has always amused me how in the dawn of Java people constantly
> preached how Java was like "C++ done right", yet it seems to lack most
> things which are *good* and/or useful in C++, like RAII, destructors,
> typedefs, enums, templates, multiple inheritance, handling objects by
> value, operator overloading and whatnot.)
Yep. Altho I never heard it as "C++ done right", but usually "C++ done
better." :-)
--
Darren New, San Diego CA, USA (PST)
Yes, we're traveling together,
but to different destinations.
Post a reply to this message
|
![](/i/fill.gif) |