如果之前有人问过这个问题,我很抱歉,我努力寻找类似的东西,但我甚至不知道要搜索什么。什么是定义自引用界面的正确方法?
假设我有如下界面(这只是一个例子,我的具体情况什么都没有与运营商或除做):
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只是一个小挑逗,但我仍然想知道是否有更好的方法)。
备注:设计加运算符对于开放类层次结构的直观工作很困难。只保留a + b = b + a是一个巨大的挑战。令人信服的基类正确地添加一些非常派生的类也很有趣.. –
我不会在运行时多态接口中使用这样的运算符,也就是说。虚拟运营商。这将极大地限制您的代码的灵活性。在处理算术运算符时考虑使用编译时多态性和泛型编程。 –