定义自引用接口的正确方法是什么?
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给助手一个。
很抱歉,如果以前有人问过这个问题,我努力寻找类似的东西,但我什至不确定要搜索什么。
假设我有以下界面(这只是一个例子,我的具体情况与运算符或加法无关):
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给助手一个。