| re: Any way to get rid of the cast when calling get_value()?
"Eric Lilja" <ericliljaNoSpam@yahoo.com> wrote in message
news:d0vita$rch$1@news.island.liu.se...[color=blue]
> Hello, I have a std::vector storing pointers to an abstract base class
> OptionBase. OptionBase is not templated but I am deriving a template class
> called Option from OptionBase. The class Option has a public member[/color]
function[color=blue]
> called get_value() that is not present in the class OptionBase. My problem
> is that when calling get_value() I have to cast to Option<some_type>* and[/color]
I[color=blue]
> was wondering if I can somehow remove the cast so I dont have to remember
> exatly what type Option is instantiated with.
>
> Some code to clarify:
>
> typedef Option<string> StringOption;
> typedef Option<long> LongOption;
>
> vector<OptionBase*> options(8);
>
> options[0] = new StringOption("Name=");
> options[1] = new StringOption("Process=");
> options[2] = new LongOption("Level=");
> options[3] = new StringOption("Technique=");
> options[4] = new StringOption("Knowledge=");
> options[5] = new StringOption("Device=");
> options[6] = new StringOption("Primary components=");
> options[7] = new StringOption("Build components=");
>
> /* Is there a way to remove these casts so I dont have to remember
> exactly what type I used to instantiate Option at each element? */
> ((StringOption*)options[0])->get_value(), /* name */
> ((StringOption*)options[1])->get_value(), /* process */
> ((LongOption*)options[2])->get_value(), /* level */[/color]
[...]
When possible, the preferred way to downcast to a subclass from a base is
dynamic_cast, because it will perform a runtime check to see if the cast
succeeded (correct type) or failed (wrong type). The C-style casts that you
are using won't do that.
To answer your question, you could have multiple member functions:
virtual long OptionBase::get_long_value();
virtual std::string OptionBase::get_string_value();
They could either throw exceptions if the type doesn't match, or attempt to
convert between the types to satisfy the request. You'd still need to know
the "correct" or "compatible" type(s) before calling the members, though.
This approach would be fine if the number of option types was small and
unchanging, but it might get ugly if more and more types had to be added
later.
--
David Hilsee |