2015-10-17 104 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。