2014-02-27 23 views
1

我有一個接口IOperandC++:模板構件加法函數

class IOperand 
{ 
    public: 
    virtual IOperand * operator+(const IOperand &rhs) const = 0; 
    virtual std::string const & toString() const = 0; 
} 

和類Operand

template <class T> 
class Operand : public IOperand 
{ 
    public: 
    virtual IOperand * operator+(const IOperand &rhs) const; 
    virtual std::string const & toString() const; 
    T value; 
} 

IOperand類和成員功能operator+toString原型不能被修改。 成員函數operator +必須添加2個包含在2 IOperand中的值。我的問題是,這個值可以是一個int,一個字符或一個浮點數,但我不知道如何使用模板。我曾經嘗試這樣做:

template <typename T> 
IOperand *    Operand<T>::operator+(const IOperand &rhs) const 
{ 
    Operand<T> *op = new Operand<T>; 
    op->value = this->value + rhs.value; 
    return op; 
} 

toString方法:

template <typename T> 
std::string const &  Operand<T>::toString() const 
{ 
    static std::string s; // Provisional, just to avoid a warning for the moment 
    std::ostringstream convert; 
    convert << this->value; 
    s = convert.str(); 
    return s; 
} 

但是編譯器未找到this->valuerhs.value,因爲他們在IOperand不是。

編輯:正如評論中的建議,我在OperandIoperand中添加了toString方法,我真的不知道它是否有幫助。

+0

是'class操作數:public操作數'應該是'class操作數:public IOperand'? – dtyler

+0

是的,編輯完成。 –

+0

請不要返回指針:您的操作符是內存泄漏 - 在使用模板之前獲取基本知識。 –

回答

0

歡迎來到二元運算符的美妙詞彙。那你想發生時,你這樣做:

IOperand* foo = new Operand<Matrix<Complex>>; 
IOperand* bar = new Operand<Polynomial<FiniteField<5>>>; 
IOperand* baz = *foo + *bar; 

基本上有兩種可能的答案。你想要一個編譯錯誤,或者你想要一個運行時錯誤。後者很容易通過dynamic_cast實現,前者通過丟棄設計,CS大學課程,然後博士,然後創建自己的二元操作理論並創建自己的OO語言很容易實現。

當然,在做所有這些時,不要忽略內存泄漏等世俗事情。

+0

你的意思是'* foo + * bar',對吧? – Angew

+0

是的,當然;) –

0

定義與類型名稱牛逼IOperandas模板類

添加T get_value()class IOperand應該工作,

超載此功能操作數,這樣你就可以獲取在子類中定義的數據

+0

看到'IOperand'對'T'完全不瞭解,這個答案沒有任何意義。 .. – Angew

+0

'Operand' *已經是一個模板。 'IOperand'不是,並且每個OP都不能被改變(並且使它成爲一個模板將會破壞它的目的)。 – Angew

3

如果IOperand真的碰不得,你將不得不求助於dynamic_cast

template <typename T> 
IOperand * Operand<T>::operator+(const IOperand &rhs) const 
{ 
    if (const Operand<T> *arg = dynamic_cast<const Operand<T>*>(&rhs)) 
    { 
    Operand<T> *op = new Operand<T>; 
    op->value = this->value + arg->value; 
    return op; 
    } 
    else 
    return NULL; // Or any other sensible "error occured" 
} 

dynamic_cast只有在rhs實際上是與調用operator +Operand<T>相同的實例時纔會成功。然後在if中檢查。

但是,讓我說明這是可怕的設計。運算符應該被重載以儘可能地像內置運算符那樣運行(除非您以域語言風格使用它們)。在std::string上使用+不會導致指向動態分配的std::string

不考慮代碼的可讀性,它錯誤的主要原因是它很容易泄漏內存 - 這個operator+的唯一明智的實現將動態分配內存,並且因爲它返回一個原始指針,所以它留給調用者確保內存不泄漏。 不好的東西。

+0

@DieterLücking也許你可以解釋如何避免這個 – 4pie0