views:

59

answers:

1

hello,

I want to send data and a capability description to a remote site. Upon receiving the data at the remote site, I want to look at the description and create an object (via a factory method ) doing exactly what I want when I invoke exec on it.

Examples:

1) send [3, (add 5) ] => receive(obj); obj->exec() -> 8

2) send [3, (add -1, mult 2) ] => receive(obj); obj->exec() -> 4

I thought of having adder and multer classes in some form of multiple inheritance but could not figure out anything as this involves creating lots of classes from different permutations of capabilities. I think I'll need to learn something :) templates? My main concern is to have zero conditionals in the exec() function also easily add new capabilities.

thanks

A: 

You say that you don't want to build separate classes for different permutations of abilities, to which I agree. But can you separate out your "abilities" into a set of atomic operations, and another set of combinators. If they all derive from a common 'executor' object, with a virtual 'exec' method, that might do the trick:

class executor {
  public:
  virtual double exec();
};

class constant_exec : public executor {
  public:
  constant_exec(double value) : m_value(value) {}
  double exec() {return m_value;}
  private:
  double m_value;
};

class add_op : public executor {
  public:
  add_op(executor const *lhs, executor const* rhs) : m_lhs(lhs), m_rhs(rhs){}
  double exec() {return rhs->exec + lhs->exec;}
  private:
  executor const* m_rhs, m_lhs;
};
  ... and so on

This way you can build up arbitrarily complicated operations. You do need to worry about correctly disposing of the executor objects, so you may wish to consider using shared (and possibly weak) pointers, though that will have some slight impact on performance.

-matt

Matthew Hall
Thanks for your time. Is this going to be a parse tree in the end? I don't see how I can combine different operations in this manner.
perreal
Well, it's at least an evaluation tree. In the second example above, the constructed object would look like: <code> new mul_op(new const_exec(2), new add_op( new const_exec(-1), new const_exec(3))) </code>. If your messages are just chains of multiply/add, that should be easy to construct.
Matthew Hall