SAX/DOM IDL -> C++ Mapping / Confused

Glenn R. Kronschnabl (grk@arlut.utexas.edu)
Thu, 12 Feb 1998 14:35:37 -0600


Hi,

I was trying to duplicate the SAX/DOM java stuff in C++ (and interface with
SP). Now, I am a IDL newbie, but according the DOM spec, Node is defined to
be just an interface. In the SAXDOM code that's straightforward since java
understands interfaces. HOWEVER, in C++, according to the IDL -> C++ mapping,
an interface is supposed to be constructed as a ABSTRACT base class using pure
virtual functions. The problem is when I try to enumerate over them, I get a
'can't cast up from a virtual base class' error. Here is abbreviated source.
Obviously, I am making a fundamental mistake. Can some kind person out there
clue me in? Thanks.

grk$ g++ n.cc
n.cc: In function `int main()':
n.cc:82: cannot cast up from virtual baseclass `Node'

----- cut here ---
#include <list>
#include <string>

class NodeList;
class NodeEnumerator;

class Node {
enum NodeType {DOCUMENT, ELEMENT};
public:
virtual NodeType getNodeType() = 0;
virtual Node* getParentNode() = 0;
virtual NodeList* getChildren() = 0;
};

class Element : public virtual Node {
public:
virtual string getTagName() = 0;
virtual NodeEnumerator* getElementsByTagName() = 0;
};

class SaxNode : public virtual Node {
public:
NodeType type;
Node* parent;
NodeList* children;

virtual NodeType getNodeType() { return type; }
virtual Node* getParentNode() { return parent; }
virtual NodeList* getChildren() { return children; }
};

class SaxElement : public virtual Node, public Element, public SaxNode {
public:
string tagName;
virtual NodeEnumerator* getElementsByTagName() { }
virtual string getTagName() { return string("SaxElement"); }
};

class NodeList {
public:
virtual NodeEnumerator* getEnumerator() = 0;
};

class SaxNodeEnumerator;

class SaxNodeList: public list<SaxNode*>, public NodeList {
public:
virtual NodeEnumerator* getEnumerator() { }
};

class NodeEnumerator {
public:
virtual Node* getFirst() = 0;
};

class SaxNodeEnumerator : public NodeEnumerator {
public:
Node* getFirst() { }

};

main()
{

SaxElement se;

SaxNodeList* list = (SaxNodeList*) se.getChildren();

SaxNodeList::iterator snode = list->begin();

for (; snode != list->end(); ++snode)
{
(*snode)->getNodeType();

SaxElement* elem = (SaxElement*) (*snode);

elem->getTagName();

SaxNodeEnumerator* e2 = (SaxNodeEnumerator*) elem->getElementsByTagName();

SaxNode* s2 = (SaxNode*) e2->getFirst();

// SaxNode snode = (SaxNode*) (*node);
// cout << node->getNodeType() << endl;
}

}
--- cut here ----

Cheers,
Glenn
--------------------
Glenn R. Kronschnabl
Applied Research Laboratories | grk@arlut.utexas.edu (PGP/MIME ok)
The University of Texas at Austin | http://www.arlut.utexas.edu/~grk
PO Box 8029, Austin, TX 78713-8029 | (Ph) 512.835.3642 (FAX) 512.835.3808
10,000 Burnet Road, Austin, TX 78758 | ... but an Aggie at heart!