"Markus Dehmann" <ma*******@gmx.de> wrote in
news:op**************@news.cis.dfn.de:
On Tue, 01 Jun 2004 19:19:50 GMT, Phlip <ph*******@yahoo.com> wrote:
Markus Dehmann wrote:
I defined a base class in order to put heterogeneous values into a
standard container: All values that I store in the container are
derived from my base class.
Now when I iterate over the elements of the container and want my
original values back - can I avoid excessive casting and if
statements? (see my sample code below.) Can I make it more elegant?
Generally, you need to read news:comp.object 's endless threads about
downcasting.
Specifically...
class Value{
public:
virtual ~Value(){}
virtual void stream(ostream & o) const = 0;
};
ostream & operator<<(ostream &o, Value const & val)
{
val.stream(o);
return o;
}
Now provide a custom implementation of stream() for each derived
type.
Thanks. Actually, I don't want to do anything with streams. I really
want the original float or string etc value back. Insofar, my code
example was misleading:
void processFloat(const float &f){
cout << "Float: " << f << endl;
}
It should be sth like:
float processFloat(const float &f){
return f * 10.0; // do sth with float
}
Did you consider using the visitor pattern?
E.g. (derived from original example)
#include <vector>
#include <string>
#include <iostream>
#include <algorithm>
using std::vector;
using std::string;
using std::ostream;
using std::cout;
using std::for_each;
// need a forward decl.
template <class T> class SpecVal;
// visitor ABC
class Visitor {
public:
virtual ~Visitor() { }
virtual void operator()(SpecVal<float>&) const = 0;
virtual void operator()(SpecVal<string>&) const = 0;
};
// value ABC
class Value {
public:
virtual ~Value() { }
virtual void apply(Visitor const&) = 0;
};
// concrete value
template <class T>
class SpecVal : public Value {
T m_t;
public:
SpecVal(T const& t = T()) : m_t(t) { }
T& get() { return m_t; }
virtual void apply(Visitor const& v) { v(*this); }
};
// visitor implementation
class PrintVisitor : public Visitor {
ostream& out;
public:
PrintVisitor(ostream& out) : out(out) { }
virtual void operator()(SpecVal<float>& val) const
{ cout << "float:" << val.get() << '\n'; }
virtual void operator()(SpecVal<string>& val) const
{ cout << "string:" << val.get() << '\n'; }
};
int main() {
vector<Value*> v;
v.push_back(new SpecVal<float>(3.5f));
v.push_back(new SpecVal<string>("test"));
PrintVisitor visitor(cout);
vector<Value*>::iterator it(v.begin());
for (; it != v.end(); ++it)
(*it)->apply(visitor);
return 0;
}
--
:: bartekd [at] o2 [dot] pl