我遇到了这个设计问题。这是故事:
我有一个基类,它定义了一些这样的方法:
virtual double & f(double x);
在回答某些查询时,基类将调用其中一个来请求对子类中某些数据的引用。问题是,这些 f 方法在子类中返回一条可选的数据。换句话说,根据子类, f 要求返回的内容可能根本不存在。基类中的逻辑可以保证在子类不存在的时候不会调用这样的f(),所以原则上这个子类不需要实现这个方法,但是我不想做方法纯虚拟,因为无论如何子类都需要可实例化。不方便的是 f 的返回类型需要引用,所以我不能简单地返回一些垃圾值。
所以基本上我正在寻找一种“优雅”的方式来返回一个虚拟引用,如果程序正常工作,无论如何都不会调用它,但理想情况下会通过捕获错误调用来帮助调试。f 的签名对于可读性很重要,所以理想情况下我不想更改它。
我想我可以在类中声明一个虚拟的静态双精度 DATA_NOT_EXIST 变量并返回它,但它看起来有点难看。有更好的想法吗?当你不得不返回“null”引用时,你最喜欢的方式是什么?
提前致谢。
编辑:
我想将这些方法保留在基类中,尽管在子类中声明它们似乎更好,因为基类试图处理一些不适用于所有子类的逻辑(这本身是一个糟糕的设计吗?)。像这样:基类代表鼠标,子类中的可选数据代表左/中/右按钮。任何特定的子类可能没有某些按钮,但无论如何基类仍然处理按钮点击,假设可能有也可能没有按钮。
编辑:这里有一些源代码来说明我的意思。在基类中:
#include <cassert>
struct Base
{
double & basef(int x)
{
assert(x >= 0 && x < 20);
if (x < 10) return f1(x);
else return f2(x);
}
virtual double & f1(int x);
virtual double & f2(int x);
};
struct Sub1 : Base
{
double & f1(int x) { return a[x]; }
double & f2(int x) { return b[x - 10]; }
double a[10];
double b[10];
};
struct Sub2 : Base
{
double & f1(int x) { return a[x]; }
double & f2(int x) { /* nothing to return here! */ }
double a[10];
};