定义自引用接口的正确方法是什么?

What is the proper way to define self-referencing interface?

很抱歉,如果以前有人问过这个问题,我努力寻找类似的东西,但我什至不确定要搜索什么。

假设我有以下界面(这只是一个例子,我的具体情况与运算符或加法无关):

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

但是我对我的解决方案并不完全满意,因为我仍然需要至少定义一个操作,但代码没有明确强制执行,忘记定义一个会导致非常难以描述的错误消息"Stack overflow"。我可以保留第一个示例中的接口,以确保每个 class 实现它都定义了所需的方法,但这反过来会在非简单情况下导致大量冗余代码。

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

PS:我知道我可以只将这些方法中的一个设为纯虚拟的,但是在实现加法比减法更难的情况下我无法选择我可以定义的方法(哪个TBH 只是一个小问题,但我仍然想知道是否有更好的方法)。

最好让您的界面保持纯粹的抽象。如果您想根据 operator+() 实现 operator-() 或反之亦然,请在您的实现中执行此操作 class(es).

如果出于某种原因您真的想尽量减少实现 class(es) 必须重写的方法的数量,请考虑创建一个帮助程序 class 子 class 是您的接口并根据其他方法实现一些方法。您可以将这些方法标记为 final(C++11 功能)以禁止它们被您的实现再次覆盖 class,这将是 subclass给助手一个。