Mysterious as it sounds, this seems to be how it works. Andy H. wrote the
DOM part, so perhaps he might comment on the actual mechanisms behind the
curtain. I haven't looked much at it myself, since I'm up to my eyeballs in
the design and architecture of the core parser code. But, from a cursory
look, it makes sense. DOM_Node has just an impl pointer and all non-virtual
out of line delegation to that impl object. All of the derived classes have
no members at all and also just non-virtual out of line delegations to the
impl objectof the parent class. So there is no member layout or vtable
layout issue at all. The cast just makes available another set of methods
that you can call, which just operate on the same impl object.

A simple variation of this would be say an IntClass class. If that Int
class has no virtual methods at all and just a single int member, you can
actually do something like this (though I wouldn't necessarily recommend it
:-)

int myInt;
IntClass* pMyIntObj = (IntClass*)&myInt;
pMyIntObj += 2;

Since the class has no virtual methods, all calls to its methods are hard
coded to specific places in memory where those methods are located (fixed
up during loading of course.) If you provide a data area that exactly
matches its member data, you can cast that data area to a type of that
class and work on it. There is no v-table, so the only representation of
the object is the member field itself. That provided data area becomes the
'this' pointer and all of the methods operate on it.

Anyway, I don't want to turn this into a lesson in questionable
programming, but it illustrates the issues. And I'm not saying the DOM_Node
hiearchy stuff is like the example I gave, but it shows how this kind of
thing can work. Basically, the cast is just creating a different type of
object which points at the same implementation object. And, since all of
the methods are non-virtual, their linkage is fixed at load time so there
is no ambiguity as to where the calls go to.

Of course I could be completely wrong :-)

----------------------------------------
Dean Roddey
Software Weenie
IBM Center for Java Technology - Silicon Valley
[EMAIL PROTECTED]



Kitching Simon <[EMAIL PROTECTED]> on 01/05/2000 04:24:44 AM

Please respond to [EMAIL PROTECTED]

To:   "'[EMAIL PROTECTED]'" <[EMAIL PROTECTED]>
cc:
Subject:  RE: comments on Xerces-c for HP-UX 10.20 pa-risc2.0 (HP9000/800)



Many thanks for the reply. However, I can't say this quite adds up for me.

Here's a bit more info on the problem, and what I *think* you were
suggesting.
Any comments greatly appreciated.

What I want to do is:
  DOM_NodeList children = node.getChildList();
  for (int i=0; i<children.getLength(); ++i)
  {
    DOM_Node child = children.item(i);
    if (child.getNodeType() == DOM_Node::ELEMENT_NODE)
    {
      DOM_Element element = castNodeToElement(child); // castNodeToElement
how???
      DOM_String s = element.getAttribute("attrName");
      .....
    }
  }

Now we have (roughly) the following type structure:
  DOM_Element : public DOM_Node   // smart-pointers
  ElementImpl : public NodeImpl // real nodes

I can see that the following is valid (except for field access
restrictions), because the node.fImpl is really an ElementImpl, even though
node's fImpl pointer is typed as NodeImpl.
  DOM_Element element;
  element.fImpl = dynamic_cast<ElementImpl*> node.fImpl; // can't do this
due to fImpl being nonpublic

However, the "child" Node object I have is *really* a DOM_Node, *not* a
DOM_Element being accessed by pointer-to-base-class. Therefore, it is *not*
valid to cast this object.

The following code (which I think is what you are suggesting) is valid only
as long as a DOM_Element happens to have exactly the same bytewise memory
layout as a DOM_Node. While this will in fact currently be the case, it is
not guarunteed to be so (eg what if DOM_Element gets an extra member field
in future..)

  DOM_Element element = *(reinterpret_cast<Element_Impl*> &child);

Regards,

Simon Kitching
> -----Original Message-----
> From:   [EMAIL PROTECTED] [SMTP:[EMAIL PROTECTED]
> Sent:   Wednesday, January 05, 2000 2:07 AM
> To:     [EMAIL PROTECTED]
> Subject:     Re: comments on Xerces-c for HP-UX 10.20 pa-risc2.0
> (HP9000/800)
>
>
>
>
> >Now for the request:
> >I can't figure how to "cast" up the "hierarchy".
> >In particular, I have a DOM_Node, which is of type ELEMENT_NODE. How do
I
> >build a DOM_Element referring to the same node??
> >Yes, I can use the DOM_Node methods, but would prefer to cast it and
then
> >use the more convenient DOM_Element methods..
> >Presumably I'm missing something very simple...
> >
>
> It works in a Javaesque sort of way, via references.
>
> So its something like:
>
> DOM_Element asElem = (DOM_Element&)domNode;
>
> So you have a target element, which is by value because the DOM node
types
> are really just reference counted smart pointers that are always treated
> by
> value, and you cast the node to it by casting it as a reference to a
> DOM_Element type. I believe this is correct, though I always have to
> re-remember this when someone asks.
>
> ----------------------------------------
> Dean Roddey
> Software Weenie
> IBM Center for Java Technology - Silicon Valley
> [EMAIL PROTECTED]
>



Reply via email to