August 2021
Intermediate to advanced
450 pages
9h 36m
Chinese
我们为Date设计了一个初始化函数,它提供了重要的日期合法性检查功能。然而,如果我们使用不当的话,日期检查功能将毫无用处。例如,假定我们已经为Date定义了输出运算符<<(9.8节):
这段代码中,我们定义today后,“忘记了”立即对它进行初始化,而“某人”在我们及时调用init_day()之前就使用了它。而且“某人”认为调用add_day()是浪费时间,或许他根本没听说过这个函数,因此他亲手构造了tomorrow而不是调用add_day()。由于这些情况碰巧发生,这个程序变成了一段问题代码——而且问题非常严重。有时,而且可能是大多数时候,它工作正常,但一些小的改变就可能导致严重的错误。例如,一个未初始化的Date会产生垃圾输出,而简单地为成员变量d加1来推移日期会成为定时炸弹:当today表示月底那天时,加1操作会导致一个非法的日期。这段“问题严重的代码”最大的问题是,它看起来似乎没什么问题。
上述思考促使我们寻找更好的操作实现方式,我们需要不会被程序员忘记的初始化函数,以及被忽视的可能性很低的操作。实现这些目标的基本技术就是成员函数(member function),即将函数声明于类体内,作为类的成员。例如:
与类同名的成员函数是特殊的成员函数,称为构造函数(constructor),专门用于类对象的初始化(“构造”)。如果一个类具有需要参数的构造函数,而程序员忘记利用它初始化类对象的话,编译器会捕获这个错误。C++提供了一种专用且方便的语法来进行这种初始化: ...