Re: dynamic_cast is ugly!
On 8 mar, 00:39, "Daniel T." <danie...@earthlink.net> wrote:
Ian Collins <ian-n...@hotmail.com> wrote:
Daniel T. wrote:
On Mar 7, 3:40 pm, Ian Collins <ian-n...@hotmail.com> wrote:
On Mar 7, 2:58 pm, Ian Collins <ian-n...@hotmail.com> wrote:
There are occasions when the interface forces your
hand. For example when implementing the W3C Document
Object Model, where all of the container types are
collections of the the base object (Node). Node is
seldom used, most containers end up storing derived
objects (Elements or Attributes) that extend the
functionality of Node.
Say you have an element type with an attribute you want
to use (the link in an XHTML anchor element for instance)
and you wish to process all of these elements in a
document. The DOM interface provides a means of
extracting a list of them by name, but that list is a
list of Nodes and Node doesn't even have attributes!
I prefer to be able to write something like
dom::NodeList anchors(document.getElementsByTagName("A"));
html::Anchor a(anchors[n]);
and let the library do the conversion from Node to Anchor
under the hood. One benefit of using dynamic_cast is the
conversion will fail if the Node isn't the expected type.
I will be happy to grant that if you are coding in a
representational style instead of Object Oriented, you may
very well have to use dynamic_cast. I don't code that way,
nor do any of the libraries I use.
OK, given an interface with the restrictions I mentioned
above, how would you code it in an "OO" style?
If I was forced to use an interface with the restrictions you
mention, then I couldn't code in an OO style. So I'm not sure
how to answer your question.
So how would you design a DOM interface in your definition of OO
style?
The basic (abstract) problem that Ian has raised is that of a
heterogeneous collection of objects. It's a frequent problem,
and it's a typical example of a case where dynamic_cast is a
good solution. You basically have the choice between moving all
of the possible derived class interfaces down to the base class,
or using dynamic_cast to get at them. I find the latter
preferable (and more OO) than the former.
Note that in general, what I would avoid is dynamic_cast to a
concrete type (although there too, there might be exceptions,
e.g. when implementing a surrogate for multiple dispatch).
Generally, if I need an extended interface, I define an extended
interface (using virtual inheritance from the base interface)
with the added functionality. Concrete classes then derive from
the extended interface (or from several extended interfaces, if
they offer several extensions). Users interogate whether an
instance supports the extension by using dynamic_cast to the
extended interface.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34