假设你正在写一个自动测速程序,当汽车通过,其速度便被计算并填入一个速度收集器内:
class SpeedDataCollection
{
...
public:
void addValue(int speed); //添加一笔新数据
double averageSoFar() const; //返回平均速度
...
};
现在让我们考虑成员函数averageSoFar。做法之一就是在class内设计一个成员变量,记录至今以来所有速度的平均值。当averageSoFar被调用。只需返回那个成员变量就好。另一个做法是令averageSoFar每次被调用时重新计算平均值,此函数有权利调取收集器的每一笔速度值。
上述第一种做法会使每一个SpeedDataCollection对象变大,因为你必须为目前平均值、累积总量、数据点数每一个成员变量分配空间。然而averageSoFar却可因此十分高效;它可以只是一个返回目前平均值的inline函数。相反地,“被询问才计算平均值”会使得averageSoFar执行较慢,但每一个SpeedDataCollection对象较小。
谁能确定哪个才是更好的呢?在一台内存吃紧的机器上,并且应用中对平均值的需要不是很频繁,每次计算平均值可能会是一个更好的选择。在一个对平均值需求频繁的应用中,速度很重要,但内存充足,你可能更喜欢将平均速度保存为数据成员。这里的重要一点是通过一个成员函数来访问平均值(也就是将其封装起来),你可以在这些不同实现之间来回切换,客户端至多只需要重新编译就可以了。(通过Item31中描述的技术,你甚至可以不用重新编译)