Adrian Z.
Adrian Z.

Reputation: 934

C++ casting on the base of inheritance

I have a method called addV that accepts two parameters.

static auto addV(Value* lval, Value* rval)

The Value type is a parent class that has childs like IntegerValue, StringValue, FloatValue, etc. I never know which one of the child's will be send to addV. What would be the easiest and most elegant way of determining it and then adding it?

Example: lval = IntegerValue(10), rval = StringValue("Bruce"), return = StringValue("1Bruce")

Example: lval = StringValue("Tom"), rval = IntegerValue(2), return = StringValue("Tom2")

Example: lval = IntegerValue(1), rval = FloatValue(3.0), return = FloatValue(4.0)

I had a previous post about doing exactly this but with primitive types.

Value class:

class Value {
protected:
    typedef enum{
        UndefinedType, 
        IntegerType, 
        ObjectType, 
        FloatType, 
        StringType, 
        BooleanType, 
        Last
    } DataType;

    public:
    virtual DataType returnType(){
        return UndefinedType;
    };
};

IntegerValue class:

class IntegerValue: public Value{
public:
    int32_t val;

    IntegerValue(int32_t val) : val(val){}

    DataType returnType(){
        return Value::IntegerType;
    };
};

FloatValue class:

class FloatValue: public Value{
public:
    float val;

    FloatValue(float val) : val(val) {}

    DataType returnType(){
        return Value::FloatType;
    };
};

StringValue class:

class StringValue: public Value{
public:
    string val;

    StringValue(string val) : val(val){}

    DataType returnType(){
        return Value::StringType;
    };
};

Upvotes: 1

Views: 129

Answers (1)

W.F.
W.F.

Reputation: 13988

I would start with something like:

enum ValueTypesEnum {
   IntValueE = 0,
   FloatValueE = 1,
   StringValueE = 2
};


class Value {
public:
   virtual Value *create() = 0;
   virtual ValueTypesEnum getType() = 0;
   Value *max(Value *other) {
      if (getType() > other->getType()) {
         return this;
      } else {
         return other;
      }
   }
};


template <ValueTypesEnum MyType, class ValueT>
class ValueFactory:public Value {
public:
   ValueTypesEnum getType() {
      return MyType;
   }
   Value *create() {
      return new ValueT();
   }
};


class IntValue: public ValueFactory<IntValueE, IntValue> {
};

class FloatValue: public ValueFactory<FloatValueE, FloatValue> {
};

class StringValue: public ValueFactory<StringValueE, StringValue> {
};


Value *addV(Value *lval, Value *rval) {
   lval->max(rval)->create();
   // change to: return lval->max(rval)->create()->set(lval)->add(rval);
}

And then add the implementation of setting element in newly created value by implementing the set and add virtual methods in the concrete classes.

Upvotes: 2

Related Questions