I agree that nodes *can* be cast to elements by using the syntax
  element = (DOM_Element&) node;

However, I think that it is **really** tacky. It is exactly equivalent to:
 memcpy(element, node, sizeof(element)); // hope
sizeof(element)==sizeof(node)!

May I suggest that as an alternative, the following method be added to
DOM_Element:
  static DOM_Element dynamicCast(DOM_Node node);

This parallels the "normal" cast syntax that would be used if DOM_Element
and DOM_Node
were the real nodes rather than smart pointers:
   // can't do this because element & node are only smart pointers
   DOM_Element element = dynamic_cast<DOM_Element&>(node);
vs
  // could provide this: try and convert node to element
  DOM_Element element = DOM_Element::dynamicCast(node);

This does raise the question of what to do if the cast fails.
The c++ dynamic_cast operator returns null when casting to a pointer type,
and throws bad_cast when casting to a reference type.
I am not sure whether it would be better for DOM_Element::dynamicCast to
return a null object or throw an exception if the supplied node was not
actually referring to a DOM_Element...

The implementation would be trivial (assuming returning a null DOM_Element
on failure):

DOM_Element DOM_Element::dynamicCast(const DOM_Node &node)
{
  return DOM_Element(dynamic_cast<ElementImpl*>(node.fImpl));
}

> -----Original Message-----
> From: [EMAIL PROTECTED] [SMTP:[EMAIL PROTECTED]
> Sent: Wednesday, January 05, 2000 8:09 PM
> To:   [EMAIL PROTECTED]
> Subject:      RE: comments on Xerces-c for HP-UX 10.20 pa-risc2.0
> (HP9000/800)
> 
> 
> 
> 
> 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