2015-05-18 123 views
1

我有一個名爲addV的方法,它接受兩個參數。基於繼承的C++鑄造

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

值類型是有孩子的喜歡IntegerValue,的StringValue,的floatValue等 我從來不知道這對孩子的一個將被髮送到ADDV父類。什麼是確定它然後添加它的最簡單和最優雅的方式?

示例:LVAL = IntegerValue(10),RVAL =的StringValue( 「布魯斯」),返回=的StringValue( 「1Bruce」)

示例:lval中=的StringValue( 「湯姆」),RVAL = IntegerValue(2 ),返回=的StringValue( 「Tom2」)

示例:LVAL = IntegerValue(1),RVAL =的floatValue(3.0),返回=的floatValue(4.0)

我有一個previous post究竟這樣做,但與原始類型。

值類:

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

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

IntegerValue類:

class IntegerValue: public Value{ 
public: 
    int32_t val; 

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

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

的floatValue類:

class FloatValue: public Value{ 
public: 
    float val; 

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

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

的StringValue類:

class StringValue: public Value{ 
public: 
    string val; 

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

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

看起來你想要某種[多派遣](https://en.wikipedia.org/wiki/Multiple_dispatch#C.2B.2B)。你如何做到這一點取決於你可以獲得哪些類型的信息。例如,您的'Value'類是否有某種標籤可用於標識對象的運行時類型。 – TartanLlama

+0

像這樣的多種調度有幾種不同的策略。要考慮的取捨是查找時間(線性vs對數vs常量)和維護成本(是否更有可能在未來添加新*類型*或新*函數*)。 –

+0

給出的例子幾乎是我在不知道它有名字的情況下想出來的。那麼這將是唯一的方法之一? Value有一個名爲returnType的方法,它從枚舉列表返回類型。 –

回答

2

我就開始喜歡的東西:

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); 
} 

,然後添加通過實施具體的類的setadd虛方法設置在新創造的價值 元素的實現。

+0

這是現有代碼的重構,如果我正確地閱讀它,您將枚舉傳遞給類?增加類將只是將要使用這種結構的少數幾個之一。我以後會玩這個。 –

+0

@AdrianZ。實際上我試圖讓你具體的Value類實現獨立於枚舉值本身。它還建議,當給定兩個值類型時應該創建哪種類型的信息可以通過枚舉值等級存儲在枚舉本身中。只有在這裏沒有包含的東西是'set'和'add'值的實現,這實際上是使你的應用程序工作的重要因素。 –

+0

好吧,我想我開始明白你是如何努力去做的。我會盡快結束。 –