2017-01-01 50 views
2

如果之前有人问过这个问题,我很抱歉,我努力寻找类似的东西,但我甚至不知道要搜索什么。什么是定义自引用界面的正确方法?

假设我有如下界面(这只是一个例子,我的具体情况什么都没有与运营商或除做):

class AddAndSub 
{ 
public: 
    virtual AddAndSub operator +(AddAndSub const &) = 0; 
    virtual AddAndSub operator -(AddAndSub const &) = 0; 
} 

由于a + b可以表示为a - (-b)a - b作为a + (-b)(为简单让我们假设所有派生类型的否定都是明确的)我的第一本能是在实现中模拟这个属性,所以只需要明确定义其中一个操作符:

class AddAndSub 
{ 
public: 
    virtual AddAndSub operator +(AddAndSub const & b) 
    { 
    return *self - (-b); 
    } 
    virtual AddAndSub operator -(AddAndSub const & b) 
    { 
    return *self + (-b); 
    } 
} 

但是我对我的解决方案并不完全满意,因为我仍然需要定义至少一个操作,但是它没有被代码明确强制执行,并且忘记了定义一个导致非常不明确的错误消息的结果“堆栈溢出”。我可以像第一个例子中那样保留接口,以确保每个实现它的类定义了所需的方法,但是这样会导致非平凡情况下的大量冗余代码。

有没有一种合适的方法来减少这种情况下的代码冗余,同时仍然保持编译时间检查并将选择哪些方法实现给接口用户?

PS:我知道我可以让这些方法之一纯虚拟,但是我不能选择哪种方法,我可以定义在一个情况下,当实施加法比减法更难(TBH只是一个小挑逗,但我仍然想知道是否有更好的方法)。

+0

备注:设计加运算符对于开放类层次结构的直观工作很困难。只保留a + b = b + a是一个巨大的挑战。令人信服的基类正确地添加一些非常派生的类也很有趣.. –

+1

我不会在运行时多态接口中使用这样的运算符,也就是说。虚拟运营商。这将极大地限制您的代码的灵活性。在处理算术运算符时考虑使用编译时多态性和泛型编程。 –

回答

1

最好保持界面纯粹抽象。如果你想用operator +()来实现operator-(),反之亦然,那么在你的实现类中(es)。

如果出于某种原因,您确实想要最大限度地减少您的实现类必须覆盖的方法数量,请考虑创建一个辅助类,它将接口子类化并按照其他方法实现一些方法。您可以将这些方法标记为最后的(C++ 11功能)禁止它们再次被您的实现类重写,这将是继承类的子类。

+0

帮助程序类看起来像是我的问题的解决方案,但是我希望更像Haskell'Eq',它只需要'=='或'!='来工作。 –

相关问题