2015-10-17 105 views
1

比方說,我有,我想解方程的程序(像這樣)指針和引用+運算符重載

Number x; 
Func fw = x * 4 + x * x; 
std::cout << fw(6.0) << "\n\n"; 

因此,我從寫抽象基類,在這裏我都開始我需要解決這個方程。

class Base 
{ 
public: 
    Base(){}; 
    virtual Base* operator*(Base& x) = 0; 
    virtual Base* operator*(double x) = 0; 
    virtual Base* operator+(Base& x) = 0; 
}; 

和班級數

class Number : public Base 
{ 
public: 
    virtual Base* operator*(Base& x); 
    virtual Base* operator*(double x); 
    virtual Base* operator+(Base& x); 
}; 

和類Func鍵與拷貝構造函數(或者至少,我思,它的拷貝構造函數)

class Func: public Base 
{ 
    Base * func; 
public: 
    Func(Base* other) 
    { 
     func = other; 
    } 

    Func(Base& other) 
    { 
     func = &other; 
    } 

    virtual Base* operator*(Base& x){} 

    virtual Base* operator*(double x){} 

    virtual Base* operator+(Base&){} 

}; 

所以,我的問題。我的程序適用於x*xx*4,但是當我嘗試將它們結合使用時x*x + x*4我遇到問題。

很明顯(或者不是)什麼is.After x*x我的程序返回指針(基地*),並在我的重載運算符的問題,我只有(基地&)。 所以程序無法匹配任何重載的操作符。

下面是克利翁顯示我binary operator + can't be applied to the expression of type Base* and Base*

因此,解決方案可以是重載操作一次,但與參數(基地*),但我希望有一個更好的辦法來解決這個問題。在那兒?

+0

例如,基本數據類型不支持直接添加float和int。取而代之的是一種促銷,int在這種情況下是浮動的。也許你可以用類似的方式解決問題。將您的不同類型提升爲相同類型,然後執行操作。 –

回答

1

是的,有:寫一個使用值或引用語義而不是指針語義的包裝類。例如,

class BaseRep // I've renamed your `Base` class 
{ 
public: 
    BaseRep(){}; 
    virtual std::unique_ptr<BaseRep> multiply(const BaseRep& x) = 0; 
}; 

class Base 
{ 
    std::unique_ptr<BaseRep> ptr; 
public: 
    Base(std::unique_ptr<BaseRep> &&p):ptr(p) {} 
    BaseRep& rep() { return *ptr; } 
    const BaseRep& rep() const { return *ptr; } 
    // and other stuff 
}; 

Base operator*(const Base &x, const Base &y) 
{ 
    return Base(x.rep().multiply(y.rep())); 
} 
+0

你不需要虛擬析構函數嗎? –

+0

@ Neil:是的;這個例子並不是要成爲一個完整的圖書館,而只是想法基本要素的示範。 (另外,我責備我從OP的帖子中複製粘貼編輯的事實) – Hurkyl

0

所有算術運算符都應該返回一個引用(或一個副本),絕對不是指針。

+2

通過複製片返回;通過引用泄漏(或懸掛)返回。真正的答案是「這個設計完全破碎」。 –

+1

@ T.C。我贊同你。但是,我必須編寫這樣的程序:C –

+1

易於修復。多態概念應該由非多態句柄類擁有。然後爲這個多態概念添加一個克隆方法,並根據這個方法實現副本。當然,當添加兩個不同的對象時,您需要一些解決動態分派的方法....或者您可以使用'boost :: variant'。 –

0
template < size_t Index > 
struct placeholder { 
    template < typename ... Args > 
    auto operator()(Args ... args) const 
    { 
     auto tpl = std::make_tuple(args...); 
     return get<Index>(tpl); 
    } 

}; 

placeholder<0> _1; 
placeholder<1> _2; // etc... 

template < typename T > 
struct val 
{ 
    T value; 
    val(T v) : value(v) {} 

    template < typename ... Args > 
    auto operator()(Args ...) const { return value; } 
}; 

template < typename LH, typename RH > 
struct plus_operator 
{ 
    plus_operator(LH l, RH r) : lh(l), rh(r) {} 

    LH lh; 
    RH rh; 

    template < typename ... Args > 
    auto operator()(Args ... args) const { return lh(args...) + rh(args...); } 
}; 

template < size_t I, typename T > 
auto operator + (placeholder<I> lh, T rh) 
{ 
    return plus_operator<placeholder<I>,T>{lh,val<T>{rh}}; 
} 
template < typename T, size_t I > 
auto operator + (T lh, placeholder<I> rh) ... 
// because this would otherwise be ambiguous... 
template < size_t I1, size_t I2 > 
auto operator + (placeholder<I1> lh, placeholder<I2> rh) ... 

一樣同爲*, - ,/ ...

auto fun = _1 * 4 + _1 * _1; 

auto result = fun(5); 

未經測試。沒有保修。但是這個技巧是我相信你想要解決的問題。它被稱爲「表達模板」。

哦,你必須覆蓋每個可能的運營商是LH,RH ......可能是一個更好的方式使用SFINAE。