[XML-DEV Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] AttributeList in C++ SAX
[I'm aware that I should have used wstring, but I'm putting off that debate for now] As someone pointed out to me on Friday: using const string& as return values is dangerous: class sax_AttributeList { public: enum AttrType { undefined, CDATA, ... }; virtual ~sax_AttributeList(); virtual int getLength() const = 0; virtual const string& getName(int i) const = 0; virtual AttrType getType(int i) const = 0; virtual const string& getValue(int i) const = 0; virtual AttrType getType(const string& name) const = 0; virtual const string& getValue(const string& name) const = 0; }; Before you know it you'll be tempted to assign the return values to local string& variables to get shorter syntax, ie. like this: ... string& aname = empty(); for (int i=0; i<atts->getLength(); ++i) { aname = atts->getName(i); ... which will result in copying the contents of the return value of getName into empty(), which is probably not the effect you're looking for. This leaves us with the alternatives of returning string*: class sax_AttributeList { public: enum AttrType { undefined, CDATA, ... }; virtual ~sax_AttributeList(); virtual int getLength() const = 0; virtual const string* getName(int i) const = 0; virtual AttrType getType(int i) const = 0; virtual const string* getValue(int i) const = 0; virtual AttrType getType(const string& name) const = 0; virtual const string* getValue(const string& name) const = 0; }; (returning a NULL pointer if not successful) or alterativelt, we can return an error code, and give a reference to the return value as a function argument, ie.: class sax_AttributeList { public: enum AttrType { undefined, CDATA, ... }; virtual ~sax_AttributeList(); virtual int getLength() const = 0; virtual bool getName(int i, string& name) const = 0; virtual bool getType(int i, AttrType& t) const = 0; virtual bool getValue(int i, string& val) const = 0; virtual bool getType(const string& name, AttrType& typ) const = 0; virtual bool getValue(const string& name, string& val) const = 0; }; In both cases we'll end up assigning to a local variable and do some testing: ... const string* s; s = atts.getName(1); if (s) { ... and ... string name; if (atts.getName(1,name)) { ... Even though it is a departure from the Java and (probably) Python implementations, I much prefer the latter alternative, because: 1. it supports very late UTF-8 decoding and copying from char* into the string class (if I use expat there has to be at least one such copy) 2. I can avoid building some of the data structures in the expat attribute list wrapper, minimizing the need for the mutable hack (casting this to a non const* "that" in const functions that do lazy evaluation and caching of variables) 3. I let the caller handle string object creation and destruction, again this minimizes copying (both gcc and MSVC++ string does shallow copying and deep-copy-on-write, but others (eg. SGI string) always do a deep copy) and eases memory management 4. The bool return value can be changed to an enum and can return more exact errors, eg. NoTypeSupport, OutOfBounds xml-dev: A list for W3C XML Developers. To post, mailto:xml-dev@i... Archived as: http://www.lists.ic.ac.uk/hypermail/xml-dev/ and on CD-ROM/ISBN 981-02-3594-1 To unsubscribe, mailto:majordomo@i... the following message; unsubscribe xml-dev To subscribe to the digests, mailto:majordomo@i... the following message; subscribe xml-dev-digest List coordinator, Henry Rzepa (mailto:rzepa@i...)
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|