我是C++的初学者,作业要求我们记录我们的代码(序言,以及函数的事前条件).我想知道它们如何适用于我的学生课程?
特别是,序言究竟是什么意思?对于我的获取方法,前后条件是什么?我觉得他们真的是为了更高级的功能(这些人改变了数据的价值)?
class Student:
{
public:
// Constructor for the student class, require 4 parameters
// In the order of string (first name), string (last name),
// integer (student ID), string (major)
Student(string myFirstName, string myLastName, int myID, string myMajor)
{
firstName = myFirstName;
lastName = myLastName;
uid = myID;
major = myMajor;
}
// Get function for the student's first name
// Return the student's first name
string getFirstName()
{
return firstName;
}
.....
private:
string firstName; // Student's first name
string lastName; // Student's last name
int uid; // Student's ID number in a number format
string major; // Student's major
};
Run Code Online (Sandbox Code Playgroud)
preamble是一个源代码注释,出现在记录其行为的函数之前,通常是像doxygen这样的工具可以自动创建有用的文档.
一个好的文档策略是记录所有不明显的内容,不记录任何内容.在此基础上,我会说你的getXXX()没有前置条件或后置条件值得记录.像"必须在正确构造的对象上调用"之类的东西只是浪费了读者的时间,就像"调用者将收到学生特定的XXX数据的副本"这样的后置条件.不要这样做!值是否合法地为空字符串的问题是构造函数的一个问题(或者甚至可能是类不变量 - 类保持为true,例如,如果值为空则使构造函数抛出并且不提供函数擦除值),而不是get功能文档.
同样,你对firstName,lastName和major的评论绝对没有任何价值,但你的评论uid确实增加了价值 - 记录字符串格式的要求!从那以后我可以告诉你错误,因为这个领域是一个int,并且有一些东西需要调查和纠正.但更一般地说,假设你有一个字符串类型 - 注释可能会有用地传达对id格式的一些限制,比如这些id与其他API或源有关,举个例子等等.
更一般地说,前提条件不仅适用于mutator(数据更改)功能.例如,一个day_for_date(int year, int month, int day)告诉您某个特定日期的星期几的函数可能有一个前提条件,即年/月/日确实描述的是说明公元1000到3000之间的有效日期.这是令人讨厌的,但这意味着如果你已经检查过某个函数调用并没有浪费时间重新验证它.在防御性编程风格(IMHO倾向于为更强大的代码制作)中,你倾向于不把它作为前提条件; 相反,接受冗余验证作为净赢(尽管如果调用者需要性能,您可以提供显式选项来禁用它),并在日期不符合预期时记录异常或错误结果.不同之处在于,前提条件是调用者必须保证函数按照文档记录操作,在防御性编程中,您通常会让调用者尝试某些内容并具有已定义/记录的可管理行为 - 状态,返回值或状态的更改以可预测的方式报告错误 - 对于广泛的先前状态和输入而言是实际的.
后置条件只对变换器有意义:在调用非变异访问器之后必须事先确定的任何关于状态的断言 - 它可能是类不变的.