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]
> >
>
>